1 /* SPDX-License-Identifier: GPL-2.0 */
4 * Provide more verbose and specific error messages instead of just "syntax
7 %define parse.error verbose
10 * Verbose error messages may contain incorrect information if LAC (Lookahead
11 * Correction) is not enabled.
13 %define parse.lac full
15 /* Avoid symbol clashes (lopsub might also expose yy* symbols). */
16 %define api.prefix {txp_yy}
19 * Although locations are automatically enabled as soon as the grammar uses the
20 * special @N tokens, specifying %locations explicitly allows for more accurate
21 * syntax error messages.
26 * Generate a pure (reentrant) parser. With this option enabled, yylval and
27 * yylloc become local variables in yyparse(), and a different calling
28 * convention is used for yylex().
32 /* Additional arguments to yylex(), yyparse() and yyerror() */
33 %param {struct txp_context *ctx}
34 %param {struct txp_ast_node **ast}
35 %param {txp_yyscan_t yyscanner} /* reentrant lexers */
39 #include "txp.bison.h"
41 int yylex(TXP_YYSTYPE *lvalp, TXP_YYLTYPE *llocp, struct txp_context *ctx,
42 struct txp_ast_node **ast, txp_yyscan_t yyscanner);
43 static void yyerror(YYLTYPE *llocp, struct txp_context *ctx,
44 struct txp_ast_node **ast, txp_yyscan_t yyscanner, const char *msg);
49 struct txp_ast_node *node;
54 %token <node> STRING_LITERAL
55 %token <node> REGEX_PATTERN
57 /* keywords with semantic value */
58 %token <node> NUM_LINES
59 %token <node> FALSE TRUE
61 /* keywords without semantic value */
64 /* operators, ordered by precendence */
68 %left LESS_THAN LESS_OR_EQUAL GREATER_OR_EQUAL REGEX_MATCH FILENAME_MATCH
71 %right NOT NEG /* negation (unary minus) */
81 /* empty */ {*ast = NULL; return 0;}
82 | string {*ast = $1; return 0;}
83 | exp {*ast = $1; return 0;}
84 | boolexp {*ast = $1; return 0;}
86 string: STRING_LITERAL {$$ = $1;}
90 | exp '+' exp {$$ = ast_node_new_binary('+', $1, $3);}
91 | exp '-' exp {$$ = ast_node_new_binary('-', $1, $3);}
92 | exp '*' exp {$$ = ast_node_new_binary('*', $1, $3);}
93 | exp '/' exp {$$ = ast_node_new_binary('/', $1, $3);}
94 | '-' exp %prec NEG {$$ = ast_node_new_unary(NEG, $2);}
95 | '(' exp ')' {$$ = $2;}
96 | NUM_LINES {$$ = txp_new_ast_leaf_node(NUM_LINES);}
99 boolexp: TRUE {$$ = txp_new_ast_leaf_node(TRUE);}
100 | FALSE {$$ = txp_new_ast_leaf_node(FALSE);}
101 | '(' boolexp ')' {$$ = $2;}
102 | boolexp OR boolexp {$$ = ast_node_new_binary(OR, $1, $3);}
103 | boolexp AND boolexp {$$ = ast_node_new_binary(AND, $1, $3);}
104 | NOT boolexp {$$ = ast_node_new_unary(NOT, $2);}
105 | exp EQUAL exp {$$ = ast_node_new_binary(EQUAL, $1, $3);}
106 | exp NOT_EQUAL exp {$$ = ast_node_new_binary(NOT_EQUAL, $1, $3);}
107 | exp '<' exp {$$ = ast_node_new_binary('<', $1, $3);}
108 | exp '>' exp {$$ = ast_node_new_binary('>', $1, $3);}
109 | exp LESS_OR_EQUAL exp {
110 $$ = ast_node_new_binary(LESS_OR_EQUAL, $1, $3);
112 | exp GREATER_OR_EQUAL exp {
113 $$ = ast_node_new_binary(GREATER_OR_EQUAL, $1, $3);
115 | string REGEX_MATCH REGEX_PATTERN {
116 $$ = ast_node_new_binary(REGEX_MATCH, $1, $3);
118 | string EQUAL string {$$ = ast_node_new_binary(EQUAL, $1, $3);}
119 | string NOT_EQUAL string {$$ = ast_node_new_binary(NOT_EQUAL, $1, $3);}
123 /* Called by yyparse() on error */
124 static void yyerror(YYLTYPE *llocp, struct txp_context *ctx,
125 __attribute__ ((unused)) struct txp_ast_node **ast,
126 __attribute__ ((unused)) txp_yyscan_t yyscanner,
129 txp_parse_error(llocp->first_line, ctx, "%s", msg);