aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jq/parse.zig
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-18 00:49:33 +0900
committernsfisis <nsfisis@gmail.com>2026-01-18 00:53:35 +0900
commit8e8fcf1dd73c785f6901cf53ce17380099d15bd1 (patch)
treee0bab2aaf525ad874ce013a3ace046ff224fc86a /src/jq/parse.zig
parent6739144edaf34d10e0c0901231b196f377007934 (diff)
downloadzgjq-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.zig54
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;