circom/parser/jaz.jison
parser/jaz.jisonRaw
1/*
2 Copyright 2018 0KIMS association.
3
4 This file is part of circom (Zero Knowledge Circuit Compiler).
5
6 circom is a free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 circom is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with circom. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20/* description: Construct AST for jaz language. */
21
22/* lexical grammar */
23%lex
24
25%%
26
27\s+ { /* skip whitespace */ }
28\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ { /* console.log("MULTILINE COMMENT: "+yytext); */ }
29\/\/.* { /* console.log("SINGLE LINE COMMENT: "+yytext); */ }
30var { return 'var'; }
31signal { return 'signal'; }
32private { return 'private'; }
33input { return 'input'; }
34output { return 'output'; }
35linearCombination { return 'linearCombination'; }
36component { return 'component'; }
37template { return 'template'; }
38function { return 'function'; }
39if { return 'if'; }
40else { return 'else'; }
41for { return 'for'; }
42while { return 'while'; }
43do { return 'do'; }
44return { return 'return'; }
45include { return 'include'; }
460x[0-9A-Fa-f]* { return 'HEXNUMBER'; }
47[0-9]+ { return 'DECNUMBER'; }
48[a-zA-Z][a-zA-Z$_0-9]* { return 'IDENTIFIER'; }
49\"[^"]+\" { yytext = yytext.slice(1,-1); return 'STRING'; }
50\=\=\> { return '==>'; }
51\<\=\= { return '<=='; }
52\-\-\> { return '-->'; }
53\<\-\- { return '<--'; }
54\=\=\= { return '==='; }
55\>\>\= { return '>>='; }
56\<\<\= { return '<<='; }
57\&\& { return '&&'; }
58\|\| { return '||'; }
59\=\= { return '=='; }
60\<\= { return '<='; }
61\>\= { return '>='; }
62\!\= { return '!='; }
63\>\> { return '>>'; }
64\<\< { return '<<'; }
65\*\* { return '**'; }
66\+\+ { return '++'; }
67\-\- { return '--'; }
68\+\= { return '+='; }
69\-\= { return '-='; }
70\*\= { return '*='; }
71\/\= { return '/='; }
72\%\= { return '%='; }
73\|\= { return '|='; }
74\&\= { return '&='; }
75\^\= { return '^='; }
76\= { return '='; }
77\+ { return '+'; }
78\- { return '-'; }
79\* { return '*'; }
80\/ { return '/'; }
81\\ { return '\\'; }
82\% { return '%'; }
83\^ { return '^'; }
84\& { return '&'; }
85\| { return '|'; }
86\! { return '!'; }
87\< { return '<'; }
88\> { return '>'; }
89\! { return '!'; }
90\? { return '?'; }
91\: { return ':'; }
92\( { return '('; }
93\) { return ')'; }
94\[ { return '['; }
95\] { return ']'; }
96\{ { return '{'; }
97\} { return '}'; }
98\; { return ';'; }
99\, { return ','; }
100\. { return '.'; }
101<<EOF>> { return 'EOF'; }
102. { console.log("INVALID: " + yytext); return 'INVALID'}
103
104/lex
105
106%left ';'
107%right 'if' 'else'
108%left EMPTY
109%left IDLIST
110%left ','
111%right '?' ':' TERCOND '=' '+=' '-=' '*=' '/=' '%=' '>>=' '<<=' '&=' '|=' '^=' '<==' '==>' '===' '<--' '-->'
112%left '||'
113%left '&&'
114%left '|'
115%left '^'
116%left '&'
117%left '==' '!='
118%left '<=' '>=' '<' '>'
119%left '<<' '>>'
120
121%left '+' '-'
122%left '*' '/' '\\' '%'
123%left '**'
124%right '++' '--' UMINUS UPLUS '!' '~'
125%left '.'
126%left DECL
127%left PLUSPLUSRIGHT MINUSMINUSRIGHT '[' ']' '(' ')'
128%left HIGH
129
130
131
132%{
133const bigInt = require('big-integer');
134const util = require('util');
135const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
136const __MASK__ = new bigInt(2).pow(253).minus(1);
137
138function setLines(dst, first, last) {
139 last = last || first;
140 dst.first_line = first.first_line;
141 dst.first_column = first.first_column;
142 dst.last_line = last.last_line;
143 dst.last_column = last.last_column;
144}
145
146%}
147
148%start allStatments
149
150%% /* language grammar */
151
152
153allStatments
154 : statmentList EOF
155 {
156// console.log(JSON.stringify($1, null, 1));
157 $$ = { type: "BLOCK", statements: $1.statments };
158 setLines($$, @1);
159 return $$
160 }
161 ;
162
163statmentList
164 : statmentList statment
165 {
166 $1.statments.push($2);
167 setLines($1, @1, @2);
168 }
169 | statment
170 {
171 $$ = { type: "STATMENTLIST", statments: [$1] };
172 setLines($$, @1);
173 }
174 ;
175
176statment
177 : functionDefinitionStatment
178 {
179 $$ = $1;
180 }
181 | templateDefinitionStatment
182 {
183 $$ = $1;
184 }
185 | ifStatment
186 {
187 $$ = $1;
188 }
189 | forStatment
190 {
191 $$ = $1;
192 }
193 | whileStatment
194 {
195 $$ = $1;
196 }
197 | doWhileStatment
198 {
199 $$ = $1;
200 }
201 | returnStatment
202 {
203 $$ = $1;
204 }
205 | block
206 {
207 $$ = $1;
208 }
209 | expressionStatment
210 {
211 $$ = $1;
212 }
213 | includeStatment
214 {
215 $$ = $1;
216 }
217 ;
218
219
220functionDefinitionStatment
221 : 'function' IDENTIFIER '(' identifierList ')' block
222 {
223 $$ = { type: "FUNCTIONDEF", name: $2, params: $4.identifiers, block: $6};
224 setLines($$, @1, @6);
225 }
226 | 'function' IDENTIFIER '(' ')' block
227 {
228 $$ = { type: "FUNCTIONDEF", name: $2, params: [], block: $5 };
229 setLines($$, @1, @5);
230 }
231 ;
232
233templateDefinitionStatment
234 : 'template' IDENTIFIER '(' identifierList ')' block
235 {
236 $$ = { type: "TEMPLATEDEF", name: $2, params: $4.identifiers, block: $6 };
237 setLines($$, @1, @6);
238 }
239 | 'template' IDENTIFIER '(' ')' block
240 {
241 $$ = { type: "TEMPLATEDEF", name: $2, params: [], block: $5 };
242 setLines($$, @1, @5);
243 }
244 ;
245
246
247identifierList
248 : identifierList ',' IDENTIFIER
249 {
250 $1.identifiers.push($3);
251 setLines($1, @1, @3);
252 }
253 | IDENTIFIER %prec EMPTY
254 {
255 $$ = { type: "IDENTIFIERLIST", identifiers: [$1] };
256 setLines($$, @1);
257 }
258 ;
259
260ifStatment
261 : 'if' '(' expression ')' statment 'else' statment
262 {
263 if ($3.type == "NUMBER") {
264 $$ = !$3.value.eq(0) ? $5 : $7;
265 } else {
266 $$ = { type: "IF", condition: $3, then: $5, else: $7 };
267 }
268 setLines($$, @1, @7);
269 }
270 | 'if' '(' expression ')' statment
271 {
272 if ($3.type == "NUMBER") {
273 $$ = !$3.value.eq(0) ? $5 : { type: "NUMBER", value: bigInt(0) };
274 } else {
275 $$ = { type: "IF", condition: $3, then: $5 };
276 }
277 setLines($$, @1, @5);
278 }
279 ;
280
281forStatment
282 : 'for' '(' expression ';' expression ';' expression ')' statment
283 {
284 $$ = { type: "FOR", init: $3, condition: $5, step: $7, body: $9 };
285 setLines($$, @1, @9);
286 }
287 ;
288
289whileStatment
290 : 'while' '(' expression ')' statment
291 {
292 $$ = { type: "WHILE", condition: $3, body: $5 };
293 setLines($$, @1, @5);
294 }
295 ;
296
297doWhileStatment
298 : 'do' statment 'while' '(' expression ')'
299 {
300 $$ = { type: "DOWHILE", condition: $5, body: $2 };
301 setLines($$, @1, @6);
302 }
303 ;
304
305returnStatment
306 : 'return' expression ';'
307 {
308 $$ = { type: "RETURN", value: $2 };
309 setLines($$, @1, @3);
310 }
311 | 'return' expression %prec ';'
312 {
313 $$ = { type: "RETURN", value: $2 }
314 setLines($$, @1, @2);
315 }
316 ;
317
318includeStatment
319 : 'include' STRING ';'
320 {
321 $$ = { type: "INCLUDE", file: $2 };
322 setLines($$, @1, @3);
323 }
324 | 'include' STRING %prec ';'
325 {
326 $$ = { type: "INCLUDE", file: $2 }
327 setLines($$, @1, @2);
328 }
329 ;
330
331block
332 : '{' statmentList '}'
333 {
334 $$ = { type: "BLOCK", statements: $2.statments };
335 setLines($$, @1, @3);
336 }
337 ;
338
339expressionStatment
340 : expression ';' %prec ';'
341 {
342 $$ = $1;
343 }
344 | expression %prec ';'
345 {
346 $$ = $1;
347 }
348 ;
349
350expression
351 : e17 %prec EMPTY
352 {
353 $$ = $1;
354 }
355 ;
356
357e17
358 : leftHandExpression '=' e17
359 {
360 $$ = { type: "OP", op: "=", values: [$1, $3] };
361 setLines($$, @1, @3);
362 }
363 | leftHandExpression '+=' e17
364 {
365 $$ = { type: "OP", op: "+=", values: [$1, $3] };
366 setLines($$, @1, @3);
367 }
368 | leftHandExpression '-=' e17
369 {
370 $$ = { type: "OP", op: "-=", values: [$1, $3] };
371 setLines($$, @1, @3);
372 }
373 | leftHandExpression '*=' e17
374 {
375 $$ = { type: "OP", op: "*=", values: [$1, $3] };
376 setLines($$, @1, @3);
377 }
378 | leftHandExpression '/=' e17
379 {
380 $$ = { type: "OP", op: "/=", values: [$1, $3] };
381 setLines($$, @1, @3);
382 }
383 | leftHandExpression '%=' e17
384 {
385 $$ = { type: "OP", op: "%=", values: [$1, $3] };
386 setLines($$, @1, @3);
387 }
388 | leftHandExpression '<<=' e17
389 {
390 $$ = { type: "OP", op: "<<=", values: [$1, $3] };
391 setLines($$, @1, @3);
392 }
393 | leftHandExpression '>>=' e17
394 {
395 $$ = { type: "OP", op: ">>=", values: [$1, $3] };
396 setLines($$, @1, @3);
397 }
398 | leftHandExpression '&=' e17
399 {
400 $$ = { type: "OP", op: "&=", values: [$1, $3] };
401 setLines($$, @1, @3);
402 }
403 | leftHandExpression '|=' e17
404 {
405 $$ = { type: "OP", op: "|=", values: [$1, $3] };
406 setLines($$, @1, @3);
407 }
408 | leftHandExpression '^=' e17
409 {
410 $$ = { type: "OP", op: "^=", values: [$1, $3] };
411 setLines($$, @1, @3);
412 }
413 | leftHandExpression '<==' e17
414 {
415 $$ = { type: "OP", op: "<==", values: [$1, $3] };
416 setLines($$, @1, @3);
417 }
418 | e17 '==>' leftHandExpression
419 {
420 $$ = { type: "OP", op: "<==", values: [$3, $1] };
421 setLines($$, @1, @3);
422 }
423 | leftHandExpression '<--' e17
424 {
425 $$ = { type: "OP", op: "<--", values: [$1, $3] };
426 setLines($$, @1, @3);
427 }
428 | e17 '-->' leftHandExpression
429 {
430 $$ = { type: "OP", op: "<--", values: [$3, $1] };
431 setLines($$, @1, @3);
432 }
433 | e16 '===' e17
434 {
435 $$ = { type: "OP", op: "===", values: [$1, $3] };
436 setLines($$, @1, @3);
437 }
438 | e17 '?' e17 ':' e17 %prec TERCOND
439 {
440 if ($1.type == "NUMBER") {
441 $$ = !$1.value.eq(0) ? $3 : $5;
442 } else {
443 $$ = { type: "OP", op: "?", values: [$1, $3, $5] };
444 }
445 setLines($$, @1, @5);
446 }
447 | e16 %prec EMPTY
448 {
449 $$ = $1;
450 }
451 ;
452
453e16
454 : rightArray
455 {
456 $$ = $1;
457 }
458 | e15 %prec EMPTY
459 {
460 $$ = $1;
461 }
462 ;
463
464e15
465 : e15 '||' e14
466 {
467 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
468 $$ = { type: "NUMBER", value: !$1.value.eq(0) || !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
469 } else {
470 $$ = { type: "OP", op: "||", values: [$1, $3] };
471 }
472 setLines($$, @1, @3);
473 }
474 | e14 %prec EMPTY
475 {
476 $$ = $1;
477 }
478 ;
479
480e14
481 : e14 '&&' e13
482 {
483 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
484 $$ = { type: "NUMBER", value: !$1.value.eq(0) && !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
485 } else {
486 $$ = { type: "OP", op: "&&", values: [$1, $3] };
487 }
488 setLines($$, @1, @3);
489 }
490 | e13 %prec EMPTY
491 {
492 $$ = $1;
493 }
494 ;
495
496e13
497 : e13 '|' e12
498 {
499 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
500 $$ = { type: "NUMBER", value: $1.value.or($3.value).and(__MASK__) };
501 } else {
502 $$ = { type: "OP", op: "|", values: [$1, $3] };
503 }
504 setLines($$, @1, @3);
505 }
506 | e12 %prec EMPTY
507 {
508 $$ = $1;
509 }
510 ;
511
512
513e12
514 : e12 '^' e11
515 {
516 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
517 $$ = { type: "NUMBER", value: $1.value.or($3.value).and(__MASK__) };
518 } else {
519 $$ = { type: "OP", op: "^", values: [$1, $3] };
520 }
521 setLines($$, @1, @3);
522 }
523 | e11 %prec EMPTY
524 {
525 $$ = $1;
526 }
527 ;
528
529e11
530 : e11 '&' e10
531 {
532 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
533 $$ = { type: "NUMBER", value: $1.value.and($3.value).and(__MASK__) };
534 } else {
535 $$ = { type: "OP", op: "&", values: [$1, $3] };
536 }
537 setLines($$, @1, @3);
538 }
539 | e10 %prec EMPTY
540 {
541 $$ = $1;
542 }
543 ;
544
545
546
547
548e10
549 : e10 '==' e9
550 {
551 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
552 $$ = { type: "NUMBER", value: $1.value.equals($3.value) ? bigInt(1) : bigInt(0) };
553 } else {
554 $$ = { type: "OP", op: "==", values: [$1, $3] };
555 }
556 setLines($$, @1, @3);
557 }
558 | e10 '!=' e9
559 {
560 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
561 $$ = { type: "NUMBER", value: $1.value.eq($3.value) ? bigInt(0) : bigInt(1) };
562 } else {
563 $$ = { type: "OP", op: "!=", values: [$1, $3] };
564 }
565 setLines($$, @1, @3);
566 }
567 | e9 %prec EMPTY
568 {
569 $$ = $1
570 }
571 ;
572
573e9
574 : e9 '<=' e7
575 {
576 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
577 $$ = { type: "NUMBER", value: $1.value.lesserOrEquals($3.value) ? bigInt(1) : bigInt(0) };
578 } else {
579 $$ = { type: "OP", op: "<=", values: [$1, $3] };
580 }
581 setLines($$, @1, @3);
582 }
583 | e9 '>=' e7
584 {
585 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
586 $$ = { type: "NUMBER", value: $1.value.greaterOrEquals($3.value) ? bigInt(1) : bigInt(0) };
587 } else {
588 $$ = { type: "OP", op: ">=", values: [$1, $3] };
589 }
590 setLines($$, @1, @3);
591 }
592 | e9 '<' e7
593 {
594 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
595 $$ = { type: "NUMBER", value: $1.value.lesser($3.value) ? bigInt(1) : bigInt(0) };
596 } else {
597 $$ = { type: "OP", op: "<", values: [$1, $3] };
598 }
599 setLines($$, @1, @3);
600 }
601 | e9 '>' e7
602 {
603 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
604 $$ = { type: "NUMBER", value: $1.value.greater($3.value) ? bigInt(1) : bigInt(0) };
605 } else {
606 $$ = { type: "OP", op: ">", values: [$1, $3] };
607 }
608 setLines($$, @1, @3);
609 }
610 | e7 %prec EMPTY
611 {
612 $$ = $1
613 }
614 ;
615
616e7
617 : e7 '<<' e6
618 {
619 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
620 let v = $3.value.greater(256) ? 256 : $3.value.value;
621 $$ = { type: "NUMBER", value: $1.value.shiftLeft(v).and(__MASK__) };
622 } else {
623 $$ = { type: "OP", op: "<<", values: [$1, $3] };
624 }
625 setLines($$, @1, @3);
626 }
627 | e7 '>>' e6
628 {
629 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
630 let v = $3.value.greater(256) ? 256 : $3.value.value;
631 $$ = {type: "NUMBER", value: $1.value.shiftRight(v).and(__MASK__) };
632 } else {
633 $$ = { type: "OP", op: ">>", values: [$1, $3] };
634 }
635 setLines($$, @1, @3);
636 }
637 | e6 %prec EMPTY
638 {
639 $$ = $1;
640 }
641 ;
642
643e6
644 : e6 '+' e5
645 {
646 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
647 $$ = { type: "NUMBER", value: ($1.value.plus($3.value)).mod(__P__) };
648 } else {
649 $$ = { type: "OP", op: "+", values: [$1, $3] };
650 }
651 setLines($$, @1, @3);
652 }
653 | e6 '-' e5
654 {
655 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
656 $$ = { type: "NUMBER", value: ($1.value.plus(__P__).minus($3.value)).mod(__P__) };
657 } else {
658 $$ = { type: "OP", op: "-", values: [$1, $3] };
659 }
660 setLines($$, @1, @3);
661 }
662 | e5 %prec EMPTY
663 {
664 $$ = $1;
665 }
666 ;
667
668
669e5
670 : e5 '*' e4
671 {
672 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
673 $$ = { type: "NUMBER", value: ($1.value.times($3.value)).mod(__P__) };
674 } else {
675 $$ = { type: "OP", op: "*", values: [$1, $3] };
676 }
677 setLines($$, @1, @3);
678 }
679 | e5 '/' e4
680 {
681 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
682 $$ = { type: "NUMBER", value: ($1.value.times($3.value.modInv(__P__))).mod(__P__) };
683 } else {
684 $$ = { type: "OP", op: "/", values: [$1, $3] };
685 }
686 setLines($$, @1, @3);
687 }
688 | e5 '\\' e4
689 {
690 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
691 $$ = { type: "NUMBER", value: ($1.value.divide($3.value)) };
692 } else {
693 $$ = { type: "OP", op: "\\", values: [$1, $3] };
694 }
695 setLines($$, @1, @3);
696 }
697 | e5 '%' e4
698 {
699 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
700 $$ = { type: "NUMBER", value: $1.value.mod($3.value) };
701 } else {
702 $$ = { type: "OP", op: "%", values: [$1, $3] };
703 }
704 setLines($$, @1, @3);
705 }
706 | e4 %prec EMPTY
707 {
708 $$ = $1;
709 }
710 ;
711
712e4
713 : e4 '**' e3
714 {
715 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
716 $$ = { type: "NUMBER", value: $1.value.modPow($3.value, __P__) };
717 } else {
718 $$ = { type: "OP", op: "**", values: [$1, $3] };
719 }
720 setLines($$, @1, @3);
721 }
722 | e3 %prec EMPTY
723 {
724 $$ = $1;
725 }
726 ;
727
728
729e3
730 : '++' leftHandExpression
731 {
732 $$ = { type: "OP", op: "PLUSPLUSLEFT", values: [$2] };
733 setLines($$, @1, @2);
734 }
735 | '--' leftHandExpression
736 {
737 $$ = { type: "OP", op: "MINUSMINUSLEFT", values: [$2] };
738 setLines($$, @1, @2);
739 }
740 | '+' e3 %prec UPLUS
741 {
742 $$ = $2;
743 setLines($$, @1, @2);
744 }
745 | '-' e3 %prec UMINUS
746 {
747 if ($2.type == "NUMBER") {
748 $$ = { type: "NUMBER", value: __P__.minus($2.value).mod(__P__) };
749 } else {
750 $$ = { type: "OP", op: "UMINUS", values: [$2] };
751 }
752 setLines($$, @1, @2);
753 }
754 | '!' e3
755 {
756 if ($2.type == "NUMBER") {
757 $$ = { type: "NUMBER", value: $2.value.eq(0) ? bigInt(1) : bigInt(0) };
758 } else {
759 $$ = { type: "OP", op: "!", values: [$2] };
760 }
761 setLines($$, @1, @2);
762 }
763 | '~' e3
764 {
765 if ($2.type == "NUMBER") {
766 $$ = { type: "NUMBER", value: $2.value.xor(__MASK__) };
767 } else {
768 $$ = { type: "OP", op: "~", values: [$2] };
769 }
770 setLines($$, @1, @2);
771 }
772 | e2 %prec EMPTY
773 {
774 $$ = $1;
775 }
776 ;
777
778e2
779 : leftHandExpression '++' %prec PLUSPLUSRIGHT
780 {
781 $$ = {type: "OP", op: "PLUSPLUSRIGHT", values: [$1] };
782 setLines($$, @1, @2);
783 }
784 | leftHandExpression '--' %prec MINUSMINUSRIGHT
785 {
786 $$ = {type: "OP", op: "MINUSMINUSRIGHT", values: [$1] };
787 setLines($$, @1, @2);
788 }
789 | functionCall
790 {
791 $$ = $1;
792 }
793 | e0 %prec EMPTY
794 {
795 $$ = $1;
796 }
797 ;
798
799e0
800 : leftHandExpression %prec EMPTY
801 {
802 $$ = $1
803 }
804 | DECNUMBER
805 {
806 $$ = {type: "NUMBER", value: bigInt($1).mod(__P__) }
807 setLines($$, @1);
808 }
809 | HEXNUMBER
810 {
811 $$ = {type: "NUMBER", value: bigInt($1.substr(2).toUpperCase(), 16).mod(__P__) }
812 setLines($$, @1);
813 }
814 | '(' expression ')' %prec EMPTY
815 {
816 $$ = $2;
817 setLines($$, @1, @3);
818 }
819 ;
820
821leftHandExpression
822 : simpleLeftHandExpression '.' simpleLeftHandExpression %prec EMPTY
823 {
824 $$ = {type: "PIN", component: $1, pin: $3 };
825 setLines($$, @1, @3);
826 }
827 | declaration %prec DECL
828 {
829 $$ = $1
830 }
831 | simpleLeftHandExpression %prec EMPTY
832 {
833 $$ = $1
834 }
835 ;
836
837
838
839declaration
840 : 'var' simpleLeftHandExpression %prec DECL
841 {
842 $$ = {type: "DECLARE", declareType: "VARIABLE", name: $2}
843 setLines($$, @1, @2);
844 }
845 | 'signal' simpleLeftHandExpression %prec DECL
846 {
847 $$ = {type: "DECLARE", declareType: "SIGNAL", name: $2}
848 setLines($$, @1, @2);
849 }
850 | 'signal' 'input' simpleLeftHandExpression %prec DECL
851 {
852 $$ = {type: "DECLARE", declareType: "SIGNALIN", name: $3};
853 setLines($$, @1, @3);
854 }
855 | 'signal' 'private' 'input' simpleLeftHandExpression %prec DECL
856 {
857 $$ = {type: "DECLARE", declareType: "SIGNALIN", private: true, name: $4};
858 setLines($$, @1, @4);
859 }
860 | 'signal' 'output' simpleLeftHandExpression %prec DECL
861 {
862 $$ = {type: "DECLARE", declareType: "SIGNALOUT", name: $3};
863 setLines($$, @1, @3);
864 }
865 | 'component' simpleLeftHandExpression %prec DECL
866 {
867 $$ = {type: "DECLARE", declareType: "COMPONENT", name: $2}
868 setLines($$, @1, @2);
869 }
870 ;
871
872simpleLeftHandExpression
873 : simpleLeftHandExpression array
874 {
875 for (let i=0; i< $2.values.length; i++) {
876 $1.selectors.push($2.values[i]);
877 }
878 setLines($1, @1, @2);
879 }
880 | IDENTIFIER %prec EMPTY
881 {
882 $$ = {type: "VARIABLE", name: $1 , selectors: []};
883 setLines($$, @1);
884 }
885 ;
886
887functionCall
888 : IDENTIFIER '(' expressionList ')'
889 {
890 $$ = {type: "FUNCTIONCALL", name: $1, params: $3.expressions}
891 setLines($$, @1, @4);
892 }
893 | IDENTIFIER '(' ')'
894 {
895 $$ = {type: "FUNCTIONCALL", name: $1, params: []}
896 setLines($$, @1, @3);
897 }
898 ;
899
900expressionList
901 : expressionList ',' expression
902 {
903 $1.expressions.push($3);
904 setLines($$, @1, @3);
905 }
906 | expression %prec ','
907 {
908 $$ = {type: "EXPRESSIONLST", expressions: [$1]};
909 setLines($$, @1);
910 }
911 ;
912
913rightArray
914 : array %prec EMPTY
915 {
916 $$ = $1;
917 }
918 ;
919
920array
921 : '[' expressionList ']'
922 {
923 $$ = { type: "ARRAY", values: $2.expressions};
924 setLines($$, @1, @3);
925 }
926 ;
927