diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-18 00:49:33 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-18 00:53:35 +0900 |
| commit | 8e8fcf1dd73c785f6901cf53ce17380099d15bd1 (patch) | |
| tree | e0bab2aaf525ad874ce013a3ace046ff224fc86a /src/jq/parse.zig | |
| parent | 6739144edaf34d10e0c0901231b196f377007934 (diff) | |
| download | zgjq-8e8fcf1dd73c785f6901cf53ce17380099d15bd1.tar.gz zgjq-8e8fcf1dd73c785f6901cf53ce17380099d15bd1.tar.zst zgjq-8e8fcf1dd73c785f6901cf53ce17380099d15bd1.zip | |
implement pipe operator
Diffstat (limited to 'src/jq/parse.zig')
| -rw-r--r-- | src/jq/parse.zig | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/src/jq/parse.zig b/src/jq/parse.zig index 244d2a3..26458f9 100644 --- a/src/jq/parse.zig +++ b/src/jq/parse.zig @@ -14,6 +14,7 @@ pub const AstKind = enum { object_key, literal, binary_expr, + pipe, }; pub const BinaryOp = enum { @@ -26,6 +27,7 @@ pub const Ast = union(AstKind) { object_key: []const u8, literal: *jv.Value, binary_expr: struct { op: BinaryOp, lhs: *Ast, rhs: *Ast }, + pipe: struct { lhs: *Ast, rhs: *Ast }, pub fn kind(self: @This()) AstKind { return self; @@ -76,29 +78,47 @@ pub fn parse(allocator: std.mem.Allocator, tokens: []const Token) !*Ast { } // GRAMMAR -// query := expr +// query := expr ("|" expr)* fn parseQuery(allocator: std.mem.Allocator, tokens: *TokenStream) !*Ast { - const result = try parseExpr(allocator, tokens); + var lhs = try parseExpr(allocator, tokens); + while (true) { + const token = try tokens.peek(); + if (token.kind() == .pipe) { + _ = try tokens.next(); + const rhs = try parseExpr(allocator, tokens); + const ast = try allocator.create(Ast); + ast.* = .{ .pipe = .{ + .lhs = lhs, + .rhs = rhs, + } }; + lhs = ast; + } else { + break; + } + } _ = try tokens.expect(.end); - return result; + return lhs; } // GRAMMAR -// expr := term -// | term + term +// expr := term ("+" term)* fn parseExpr(allocator: std.mem.Allocator, tokens: *TokenStream) !*Ast { var lhs = try parseTerm(allocator, tokens); - const token = try tokens.peek(); - if (token.kind() == .plus) { - _ = try tokens.next(); - const rhs = try parseTerm(allocator, tokens); - const ast = try allocator.create(Ast); - ast.* = .{ .binary_expr = .{ - .op = .add, - .lhs = lhs, - .rhs = rhs, - } }; - lhs = ast; + while (true) { + const token = try tokens.peek(); + if (token.kind() == .plus) { + _ = try tokens.next(); + const rhs = try parseTerm(allocator, tokens); + const ast = try allocator.create(Ast); + ast.* = .{ .binary_expr = .{ + .op = .add, + .lhs = lhs, + .rhs = rhs, + } }; + lhs = ast; + } else { + break; + } } return lhs; } @@ -123,7 +143,7 @@ fn parseTerm(allocator: std.mem.Allocator, tokens: *TokenStream) !*Ast { const next_token = try tokens.peek(); switch (next_token.kind()) { - .end => { + .end, .pipe, .plus => { const ast = try allocator.create(Ast); ast.* = .identity; return ast; |
