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