master
y 235 lines 7.02 KB
Raw
1 %include {
2 #include "../eval-internal.h"
3 #include "parser_internal.h"
4 #include <assert.h>
5 }
6
7 %token_type {YYSTYPE}
8 %token_prefix TOK_
9
10 %type expr {EVAL_NODE*}
11 %type program {EVAL_NODE*}
12
13 %syntax_error {
14 // Create a NOP node with count=0 as an error marker
15 EVAL_NODE *error_node = eval_node_alloc(0);
16 error_node->operator = EVAL_OPERATOR_NOP;
17 *result = error_node;
18 }
19
20 %parse_accept {
21 // Successfully parsed the expression
22 }
23
24 %parse_failure {
25 // Failed to parse the expression
26 if (*result) {
27 eval_node_free(*result);
28 *result = NULL;
29 }
30 }
31
32 %extra_argument {EVAL_NODE **result}
33
34 %destructor expr {
35 if ($$) {
36 eval_node_free($$);
37 }
38 }
39
40 // Start symbol
41 program ::= expr(E). {
42 *result = E;
43 }
44
45 // Basic expressions
46 expr(A) ::= NUMBER(B). {
47 A = eval_node_alloc(1);
48 A->operator = EVAL_OPERATOR_NOP;
49 eval_node_set_value_to_constant(A, 0, B.dval);
50 }
51
52 expr(A) ::= VARIABLE(B). {
53 A = eval_node_alloc(1);
54 A->operator = EVAL_OPERATOR_NOP;
55 eval_node_set_value_to_variable(A, 0, B.strval);
56 freez(B.strval); // Free the strdup'd string
57 }
58
59 // Parenthesized expressions
60 expr(A) ::= LPAREN expr(B) RPAREN. {
61 A = eval_node_alloc(1);
62 A->operator = EVAL_OPERATOR_EXPRESSION_OPEN;
63 A->precedence = eval_precedence(EVAL_OPERATOR_EXPRESSION_OPEN);
64 eval_node_set_value_to_node(A, 0, B);
65 }
66
67 // Unary operators
68 expr(A) ::= PLUS expr(B). [UPLUS] {
69 A = eval_node_alloc(1);
70 A->operator = EVAL_OPERATOR_SIGN_PLUS;
71 A->precedence = eval_precedence(EVAL_OPERATOR_SIGN_PLUS);
72 eval_node_set_value_to_node(A, 0, B);
73 }
74
75 expr(A) ::= MINUS expr(B). [UMINUS] {
76 A = eval_node_alloc(1);
77 A->operator = EVAL_OPERATOR_SIGN_MINUS;
78 A->precedence = eval_precedence(EVAL_OPERATOR_SIGN_MINUS);
79 eval_node_set_value_to_node(A, 0, B);
80 }
81
82 expr(A) ::= NOT expr(B). {
83 A = eval_node_alloc(1);
84 A->operator = EVAL_OPERATOR_NOT;
85 A->precedence = eval_precedence(EVAL_OPERATOR_NOT);
86 eval_node_set_value_to_node(A, 0, B);
87 }
88
89 // Function calls
90 expr(A) ::= FUNCTION_ABS LPAREN expr(B) RPAREN. {
91 A = eval_node_alloc(1);
92 A->operator = EVAL_OPERATOR_ABS;
93 A->precedence = eval_precedence(EVAL_OPERATOR_ABS);
94 eval_node_set_value_to_node(A, 0, B);
95 }
96
97 // Binary operators
98 expr(A) ::= expr(B) PLUS expr(C). {
99 A = eval_node_alloc(2);
100 A->operator = EVAL_OPERATOR_PLUS;
101 A->precedence = eval_precedence(EVAL_OPERATOR_PLUS);
102 eval_node_set_value_to_node(A, 0, B);
103 eval_node_set_value_to_node(A, 1, C);
104 }
105
106 expr(A) ::= expr(B) MINUS expr(C). {
107 A = eval_node_alloc(2);
108 A->operator = EVAL_OPERATOR_MINUS;
109 A->precedence = eval_precedence(EVAL_OPERATOR_MINUS);
110 eval_node_set_value_to_node(A, 0, B);
111 eval_node_set_value_to_node(A, 1, C);
112 }
113
114 expr(A) ::= expr(B) MULTIPLY expr(C). {
115 A = eval_node_alloc(2);
116 A->operator = EVAL_OPERATOR_MULTIPLY;
117 A->precedence = eval_precedence(EVAL_OPERATOR_MULTIPLY);
118 eval_node_set_value_to_node(A, 0, B);
119 eval_node_set_value_to_node(A, 1, C);
120 }
121
122 expr(A) ::= expr(B) DIVIDE expr(C). {
123 A = eval_node_alloc(2);
124 A->operator = EVAL_OPERATOR_DIVIDE;
125 A->precedence = eval_precedence(EVAL_OPERATOR_DIVIDE);
126 eval_node_set_value_to_node(A, 0, B);
127 eval_node_set_value_to_node(A, 1, C);
128 }
129
130 expr(A) ::= expr(B) MODULO expr(C). {
131 A = eval_node_alloc(2);
132 A->operator = EVAL_OPERATOR_MODULO;
133 A->precedence = eval_precedence(EVAL_OPERATOR_MODULO);
134 eval_node_set_value_to_node(A, 0, B);
135 eval_node_set_value_to_node(A, 1, C);
136 }
137
138 expr(A) ::= expr(B) AND expr(C). {
139 A = eval_node_alloc(2);
140 A->operator = EVAL_OPERATOR_AND;
141 A->precedence = eval_precedence(EVAL_OPERATOR_AND);
142 eval_node_set_value_to_node(A, 0, B);
143 eval_node_set_value_to_node(A, 1, C);
144 }
145
146 expr(A) ::= expr(B) OR expr(C). {
147 A = eval_node_alloc(2);
148 A->operator = EVAL_OPERATOR_OR;
149 A->precedence = eval_precedence(EVAL_OPERATOR_OR);
150 eval_node_set_value_to_node(A, 0, B);
151 eval_node_set_value_to_node(A, 1, C);
152 }
153
154 expr(A) ::= expr(B) EQ expr(C). {
155 A = eval_node_alloc(2);
156 A->operator = EVAL_OPERATOR_EQUAL;
157 A->precedence = eval_precedence(EVAL_OPERATOR_EQUAL);
158 eval_node_set_value_to_node(A, 0, B);
159 eval_node_set_value_to_node(A, 1, C);
160 }
161
162 expr(A) ::= expr(B) NE expr(C). {
163 A = eval_node_alloc(2);
164 A->operator = EVAL_OPERATOR_NOT_EQUAL;
165 A->precedence = eval_precedence(EVAL_OPERATOR_NOT_EQUAL);
166 eval_node_set_value_to_node(A, 0, B);
167 eval_node_set_value_to_node(A, 1, C);
168 }
169
170 expr(A) ::= expr(B) LT expr(C). {
171 A = eval_node_alloc(2);
172 A->operator = EVAL_OPERATOR_LESS;
173 A->precedence = eval_precedence(EVAL_OPERATOR_LESS);
174 eval_node_set_value_to_node(A, 0, B);
175 eval_node_set_value_to_node(A, 1, C);
176 }
177
178 expr(A) ::= expr(B) LE expr(C). {
179 A = eval_node_alloc(2);
180 A->operator = EVAL_OPERATOR_LESS_THAN_OR_EQUAL;
181 A->precedence = eval_precedence(EVAL_OPERATOR_LESS_THAN_OR_EQUAL);
182 eval_node_set_value_to_node(A, 0, B);
183 eval_node_set_value_to_node(A, 1, C);
184 }
185
186 expr(A) ::= expr(B) GT expr(C). {
187 A = eval_node_alloc(2);
188 A->operator = EVAL_OPERATOR_GREATER;
189 A->precedence = eval_precedence(EVAL_OPERATOR_GREATER);
190 eval_node_set_value_to_node(A, 0, B);
191 eval_node_set_value_to_node(A, 1, C);
192 }
193
194 expr(A) ::= expr(B) GE expr(C). {
195 A = eval_node_alloc(2);
196 A->operator = EVAL_OPERATOR_GREATER_THAN_OR_EQUAL;
197 A->precedence = eval_precedence(EVAL_OPERATOR_GREATER_THAN_OR_EQUAL);
198 eval_node_set_value_to_node(A, 0, B);
199 eval_node_set_value_to_node(A, 1, C);
200 }
201
202 // Ternary operator with proper precedence and associativity
203 // This rule should ensure that ternary operators are right-associative
204 // and have lower precedence than comparison operators
205 expr(A) ::= expr(B) QMARK expr(C) COLON expr(D). {
206 A = eval_node_alloc(3);
207 A->operator = EVAL_OPERATOR_IF_THEN_ELSE;
208 A->precedence = eval_precedence(EVAL_OPERATOR_IF_THEN_ELSE);
209 eval_node_set_value_to_node(A, 0, B);
210 eval_node_set_value_to_node(A, 1, C);
211 eval_node_set_value_to_node(A, 2, D);
212 }
213
214 // Operator precedence declarations - LOWEST to HIGHEST
215 // In Lemon (like yacc/bison), precedence increases as you go down the list
216 //
217 // This means:
218 // 1. Ternary operator (?:) has the lowest precedence (will be evaluated last)
219 // 2. Logical operators (AND, OR) have the next lowest precedence
220 // 3. Comparison operators (EQ, NE, LT, etc.) are next
221 // 4. Addition and subtraction come next
222 // 5. Multiplication, division, and modulo have higher precedence
223 // 6. Unary operators (-, +, !) have the highest precedence (will be evaluated first)
224
225 // The %left and %right directives specify associativity:
226 // - %left: left-associative (a + b + c is parsed as (a + b) + c)
227 // - %right: right-associative (a = b = c is parsed as a = (b = c))
228
229 %right COLON QMARK. // Ternary operator (right-associative)
230 %left OR AND. // Logical operators
231 %left EQ NE. // Equality operators
232 %left LT LE GT GE. // Comparison operators
233 %left PLUS MINUS. // Addition and subtraction
234 %left MULTIPLY DIVIDE MODULO. // Multiplication, division, and modulo
235 %right UMINUS UPLUS NOT. // Unary operators (highest precedence)