source: proto/pebble/trunk/src/parser/Pebble.g @ 1246

Last change on this file since 1246 was 1246, checked in by shermer, 8 years ago

various small changes so as to bring the output into greater conformity to python/pablo.
The input bitstream variable naming changed, from Basis_bits.bit_i to bit[i].
Pebble now accepts a$b as array indexing in input, yielding a[b] on output.
Information about user structs and their fields is now gathered and printed.

File size: 13.9 KB
Line 
1grammar Pebble;
2
3options {
4  language = Java;
5  output = template;
6}
7
8tokens {
9        FIRST;  // to distinguish unary ^ from binary (xor) ^
10}
11
12@header {
13  package parser;
14 
15  import ast.*;
16  import ast.exprNodes.*;
17  import ast.nodes.*;
18  import symbolTable.*;
19}
20
21@lexer::header {
22  package parser;
23 
24  import util.StringUtils;
25}
26
27// uses a custom token class.  See
28// http://www.antlr.org/wiki/pages/viewpage.action?pageId=1844
29@lexer::members {
30    public Object tokenData = null;
31       
32        // override standard token emission
33        public PebbleToken emit() {
34            PebbleToken token =
35                new PebbleToken(input, state.type, state.channel,
36                            state.tokenStartCharIndex, getCharIndex()-1, tokenData);
37            token.setLine(state.tokenStartLine);
38            token.setText(state.text);
39            token.setCharPositionInLine(state.tokenStartCharPositionInLine);
40                tokenData = null;
41               
42            emit(token);
43            return token;
44        }
45
46        private String trimDots(String dottedIdent) {
47                return dottedIdent.substring(1, dottedIdent.length()-1);
48        }
49}
50
51
52///////////////////////////////////////////////////////////////////////////////
53//
54//
55//
56///////////////////////////////////////////////////////////////////////////////
57
58
59
60prog returns [AST asTree]
61@init {                                         $asTree = new ProgramBlockASTN("*program*");}
62        : (b=namedBlock                 {$asTree.addChild($b.asTree);}
63        )*;
64
65namedBlock returns [AST asTree]
66    : 'defblock' id=Identifier executionBlock[$id.text, false] {
67                $asTree = $executionBlock.asTree;
68        }
69    | 'macro' id=Identifier executionBlock[$id.text, true] {
70                $asTree = $executionBlock.asTree;
71        }
72    | 'struct' id=Identifier structBlock[$id.text] {
73                $asTree = $structBlock.asTree;
74        }
75    ;
76   
77executionBlock[String name, boolean isMacro] returns [AST asTree]
78    : '{' s=statementList '}'  {
79                        $asTree = new ExecutionBlockASTN(name, isMacro);
80                        for(AST stmt: $s.stmts) {
81                                $asTree.addChild(stmt);
82                        }
83                }
84    ;
85
86structBlock[String name] returns [AST asTree]
87        : '{' d=declarationList '}' {
88                        $asTree = new StructBlockASTN(name);
89                        for(AST decl: $d.decls) {
90                                $asTree.addChild(decl);
91                        }
92                }
93    ;
94
95declarationList returns [List<AST> decls]
96@init                      {$decls = new ArrayList<AST>();}
97        :    d=declaration     {$decls.add($d.asTree);}
98        (',' d=declaration     {$decls.add($d.asTree);}
99        )* (',')?
100        ;
101
102declaration returns [AST asTree]
103        : t=variableType? i=Identifier {
104                        Type type;
105                        if(t==null) {
106                                type = PrimitiveType.Bitstream;
107                        }
108                        else {
109                                type = $t.type;
110                        }
111                       
112                        $asTree = new DeclarationASTN();
113                        $asTree.addChild(VariableASTB.make($i.text));
114                        $asTree.setType(type);
115                }
116        ;
117       
118blockStatement returns [BlockStatementASTN asTree]
119    : '{' s=statementList '}'  {
120                        $asTree = new BlockStatementASTN();
121                        for(AST stmt: $s.stmts) {
122                                $asTree.addChild(stmt);
123                        }
124                }
125    ;
126
127statementList returns [List<AST> stmts]
128@init {
129        $stmts = new ArrayList<AST>();
130}
131        : ( s=statement {
132                        $stmts.add($s.asTree);
133                        if($s.secondTree != null) {
134                                $stmts.add($s.secondTree);
135                        }
136                }
137        )+
138        ;
139       
140statement returns [AST asTree, AST secondTree]
141@init {
142        $secondTree = null;
143}
144        : i=ifStatement     {$asTree = $i.asTree;}
145        | w=whileStatement  {$asTree = $w.asTree;}
146        | a=assignStatement {$asTree = $a.firstTree;
147                                                 $secondTree = $a.secondTree; }
148        | e=expandStatement {$asTree = $e.asTree;}
149        ;
150       
151expandStatement returns [AST asTree]
152        :       'expand' i=Identifier {
153                        $asTree = new ExpandASTN($i.text);
154                }
155        ;
156       
157assignStatement returns [AST firstTree, AST secondTree]
158        : (t=assignTarget)
159          '=' expr=bExpression {
160                        AST assign = new AssignmentASTN();
161                        assign.addChild($t.variable);
162                        assign.addChild($expr.asTree);
163       
164                        if($t.decl != null) {
165                                $firstTree = $t.decl;
166                                $secondTree = assign;
167                        }
168                        else {
169                                $firstTree = assign;
170                                $secondTree = null;
171                        }
172                }
173        | (t=assignTarget) op=assignOp expr=bExpression {
174                        if($t.decl != null) {
175                                System.err.println("Error.  May not use " + $op.text + " in initialization.");
176                        }
177                       
178                        AST assign = new AssignmentASTN();
179                        assign.addChild($t.variable.copy());
180                       
181                       
182                        AST operation = null;
183                        if($op.text.equals("&=")) {
184                                operation = AndASTB.make($t.variable, $expr.asTree );
185                        }
186                        else if ($op.text.equals("|=")) {
187                                operation = OrASTB.make($t.variable, $expr.asTree);
188                        }
189                        else if ($op.text.equals("^=")) {
190                                operation = XorASTB.make($t.variable, $expr.asTree);
191                        }
192                        else if ($op.text.equals("+>=")) {
193                                operation = ScanThroughASTB.make($t.variable, $expr.asTree);
194                        }
195                       
196                        assign.addChild(operation);
197                        $firstTree = assign;
198                        $secondTree = null;
199                }
200        | (t=assignTarget) uop=unaryAssignOp  {
201                        if($t.decl != null) {
202                                System.err.println("Error.  May not use " + $uop.text + " in initialization.");
203                        }
204                       
205                        AST assign = new AssignmentASTN();
206                        assign.addChild($t.variable.copy());
207                       
208                        AST operation = null;
209                        if($uop.text.equals(">=")) {
210                                operation = ShiftASTB.make($t.variable, 1);
211                        }
212                        else if ($uop.text.equals("~=")) {
213                                operation = NotASTB.make($t.variable);
214                        }
215                       
216                        assign.addChild(operation);
217                        $firstTree = assign;
218                        $secondTree = null;
219                }
220        ;
221
222assignOp
223        : '&=' | '|=' | '^=' | '+>='
224        ;
225unaryAssignOp
226        : '>=' | '~='
227        ;
228       
229assignTarget returns [AST decl, AST variable;]
230        : t=variableType? i=Identifier {
231                        if(t!=null) {
232                                $decl = new DeclarationASTN();
233                                $decl.setType($t.type);
234                                $decl.addChild( VariableASTB.make($i.text) );
235                        }
236                        else {
237                                $decl = null;
238                        }
239                        $variable = VariableASTB.make($i.text);
240                }
241        ;
242
243variableType returns [Type type]
244        :       'output' {$type = PrimitiveType.Output;}
245        |       'errorStream'  {$type = PrimitiveType.Error;}
246        ;
247
248whileStatement returns [AST asTree]
249        : 'while' c=condition b=blockStatement {
250                        $asTree = new WhileStatementASTN();
251                        $asTree.addChild($c.asTree);
252                        $asTree.addChild($b.asTree);
253                }
254        ;
255       
256       
257ifStatement returns [AST asTree]
258    : 'if' c=condition i=ifBlocks[$c.asTree] {
259                if($i.message != null) {
260                        IfErrorStatementASTN error = new IfErrorStatementASTN();
261                        $asTree = error;
262                        $asTree.addChild($c.asTree);
263                        error.setMessage($i.message);
264                }
265                else {
266                        $asTree = new IfStatementASTN();
267                        $asTree.addChild($c.asTree);
268                        $asTree.addChild($i.trueTree);
269                        if($i.falseTree != null) {
270                                $asTree.addChild($i.falseTree);
271                        }
272                }
273        }
274    ;
275   
276ifBlocks[AST cond] returns [AST trueTree, AST falseTree, String message]
277        : 'then' tBlock=blockStatement ('else' fBlock=blockStatement)? {
278                        $message = null;
279                        $trueTree = $tBlock.asTree;
280                        if(fBlock != null) {
281                                $falseTree = $fBlock.asTree;
282                        }
283                        else {
284                                $falseTree = null;
285                        }
286                }
287        | 'simplify' b=blockStatement {
288                        $message = null;
289                        $falseTree = $b.asTree.copy();
290                       
291                        $b.asTree.addAssumption((ConditionASTN)(cond.copy()));
292                        $trueTree = $b.asTree;
293                }
294        | 'error' m=StringConstant {
295                        $message = $m.text;
296                        $falseTree = null;
297                        $trueTree = null;
298                }
299        ;
300       
301condition returns [AST asTree]
302        : e=bExpression c=conditionIndicator {
303                                int constant = $c.zeroes ? 0 : -1;
304                                $asTree = new ConditionASTN(constant, $c.complemented, $e.asTree);
305                        }
306        ;
307       
308conditionIndicator returns [boolean zeroes, boolean complemented]
309        : 'allzero' {
310                        $zeroes = true;
311                        $complemented = false;
312                }
313        | 'allone'  {
314                        $zeroes = false;
315                        $complemented = false;
316                }
317        | 'not' ci=conditionIndicator {
318                        $zeroes = $ci.zeroes;
319                        $complemented = !($ci.complemented);
320                }       
321        ;
322       
323bExpression returns [AST asTree]
324        : b=bExpression8 {
325                        $asTree = $b.asTree;
326                }
327        ;
328
329bExpression8 returns [AST asTree]
330        : b7 = bExpression7  {
331                                $asTree = $b7.asTree;
332                        }
333                (op=('+>'|'<>') b7b=bExpression7 {
334                                if($op.text.equals("+>")) {
335                                        $asTree = ScanThroughASTB.make($asTree, $b7b.asTree);
336                                }
337                                else {
338                                        $asTree = SpanASTB.make($asTree, $b7b.asTree);
339                                }
340                        }
341                )*
342         ;
343bExpression7 returns [AST asTree]       
344        // right-associative? left-associative?
345        : b6 = bExpression6 {
346                                $asTree = $b6.asTree;
347                        }
348                ('?' b7t=bExpression7 ':' b7f=bExpression6 {
349                                $asTree = SelectionASTB.make($asTree, $b7t.asTree, $b7f.asTree);
350                        }
351                )*
352        ;
353       
354bExpression6 returns [AST asTree]
355@init{
356        List<AST> bExpr5s = new ArrayList<AST>();
357}
358        : b5 = bExpression5  {
359                                bExpr5s.add(OrASTB.singleChild($b5.asTree));
360                        }
361                ((op='|' | op='^') b5=bExpression5 {
362                                if($op.text.equals("|")) {
363                                        bExpr5s.add(OrASTB.singleChild($b5.asTree));
364                                }
365                                else if($op.text.equals("^")) {
366                                        bExpr5s.add(XorASTB.singleChild($b5.asTree));
367                                }
368                                else {
369                                        System.err.println("bad or-operation in bExpression6: " + $op.text);
370                                }
371                        }
372                )* {
373                        $asTree = FalseLiteralASTB.make();
374                        for(AST expr: bExpr5s) {
375                                if(expr instanceof OrASTB) {
376                                        $asTree = OrASTB.make($asTree, expr.getChild(0));
377                                }
378                                else {
379                                        $asTree = XorASTB.make($asTree, expr.getChild(0));
380                                }
381                        }
382                }
383        ;
384       
385bExpression5 returns [AST asTree]
386@init{
387        List<AST> bExpr4s = new ArrayList<AST>();
388}
389        : b4=bExpression4 {bExpr4s.add($b4.asTree);}
390                ('&' b4=bExpression4 {bExpr4s.add($b4.asTree);} )* {
391                        $asTree = TrueLiteralASTB.make();
392                        for(AST expr: bExpr4s) {
393                                $asTree = AndASTB.make($asTree, expr);
394                        }
395                }
396//      | bExpression4
397        ;
398       
399bExpression4 returns [AST asTree]
400//      : bExpression3 (('+'^|'-'^) bExpression3)*     
401        : bExpression3 {$asTree = $bExpression3.asTree;}
402        ;
403       
404bExpression3 returns [AST asTree]
405        : bExpression2 {$asTree = $bExpression2.asTree;}
406        ;
407       
408bExpression2 returns [AST asTree]
409        : '~' expr = bExpression2 {
410                        $asTree = NotASTB.make($expr.asTree);
411          }
412        | '>' expr = bExpression2 {
413                        $asTree = ShiftASTB.make($expr.asTree, 1);
414          }
415        | bExpression1 {$asTree = $bExpression1.asTree;}
416        ;
417       
418bExpression1 returns [AST asTree]
419        : s = SequenceLiteral {
420                        PebbleToken token = (PebbleToken)s;//.token;
421                        SequenceTokenData seqData = token.sequenceData();
422                        $asTree = SequenceASTB.make(seqData);
423          }
424    | c = CharClassToken  {
425                        PebbleToken token = (PebbleToken)c;//.token;
426                        CharClassTokenData ccData = token.charClassData();
427                        ccData.seal();
428                        $asTree = CharClassASTB.make(ccData);
429                        if(ccData.isComplemented()) {
430                                $asTree = NotASTB.make($asTree);
431                        }
432      }
433    | i = Identifier {
434                        $asTree = VariableASTB.make($i.text);
435      }
436    | n = IntegerConstant {
437                int value = Integer.parseInt($n.text);
438                $asTree = ConstantASTB.make(value);
439        }
440    | 'false' {
441                $asTree = FalseLiteralASTB.make();
442        }
443    | 'true' {
444                $asTree = TrueLiteralASTB.make();
445        }
446    | '(' bExpression ')' {
447                        $asTree = $bExpression.asTree;
448      }
449    ;
450
451
452///////////////////////////////////////////////////////////////////////////////
453//
454//  Tokens
455//
456///////////////////////////////////////////////////////////////////////////////
457
458StringConstant
459        : '<<' Non_RAngle* '>>'
460        ;
461
462Identifier
463        :       IdentiFrag ;
464       
465IntegerConstant
466        :       Digit* | '-' Digit*;
467
468SequenceLiteral
469@init {
470        SequenceTokenData seqData = new SequenceTokenData();
471}
472@after {
473        // do this after, as CharClassFrag plays with tokenData, as well.
474        tokenData = seqData;
475}
476
477    :   '"' ( options {greedy = false;}:
478                  (
479                     esc = EscapeSequence {
480//                      System.out.println("seq escaped: " + $esc.text);
481//                      seqData.add(ElementType.CHAR, ""+$esc.text.charAt(1));
482                        seqData.add(SequenceTokenData.singleCharacterClassData((char)(util.StringUtils.escapeValue($esc.text))));
483                     }
484//                |  dot = ColonedIdentifier {
485//                              // System.out.println("seq dotted: " + $dot.text);
486//                      seqData.add(trimDots($dot.text));
487//                       }
488                  |  cc = CharClassFrag {
489                                // System.out.println("seq cclass: " + tokenData.toString());
490                                ((CharClassTokenData)tokenData).seal();
491                        seqData.add((CharClassTokenData)tokenData);
492                        tokenData = null;
493                         }
494                  |  oth = SequenceOtherChar {
495//                      System.out.println("seq other: " + $oth.text);
496//                      seqData.add(ElementType.CHAR, ""+$oth.text);
497                        seqData.add(SequenceTokenData.singleCharacterClassData($oth.text.charAt(0)));
498                     }
499                  )*
500            )
501        '"'
502    ;
503fragment
504SequenceOtherChar:      ~('"'|'\\'|'.'|'[') ;
505   
506CharClassToken: CharClassFrag ;
507
508fragment   
509CharClassFrag
510@init {
511        CharClassTokenData charClassData = new CharClassTokenData();
512        tokenData = charClassData;
513}
514        :       '['
515                        ('^' {charClassData.setComplemented();}) ?
516                (
517                          esc=EscapeSequence {
518                                // System.out.println("CC escaped: " + $esc.text.charAt(1));
519                                charClassData.addChar((char)(util.StringUtils.escapeValue($esc.text)));
520                          }
521//                      | col=ColonedIdentifier {
522//                              // System.out.println("CC dot: " + $dot.text);
523//                              charClassData.addStream(trimDots($col.text));
524//                        }
525                        | non=Non_Escape_RB_Caret  {
526                                // System.out.println("CC non: " + $non.text);
527                                charClassData.addChar($non.text.charAt(0));
528                          }
529                        )*
530                ']'
531        ;
532
533
534
535fragment
536ColonedIdentifier
537        :       ':' IdentiFrag ':'
538        ;
539fragment
540IdentiFrag
541//              WARNING!  dot ('.') hacked into here for allowing structure-reference!
542//                                      clean it up!
543//              '$' included for array indexing.
544        :       ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.'|'$')*
545        ;
546fragment
547Non_Escape_RB_Colon_Caret
548        :       ~('\\' | ']' | ':' | '^')
549        ;
550fragment
551Non_Escape_RB_Caret
552        :       ~('\\' | ']' | '^')
553        ;
554
555fragment
556Non_RAngle:     ~('>') ;
557       
558fragment
559EscapeSequence
560    :   '\\' ('a'..'w'| 'y'..'z'| 'A'..'Z' | '_' | '\"' | '\'' | '\\' | '[' | ']' | '.'| '-' | '^')
561        | HexEscape
562    ;
563   
564fragment
565HexEscape
566    :   '\\' 'x' HexDigit HexDigit
567    ;
568 
569fragment
570HexDigit
571        : ('0'..'9'|'a'..'f'|'A'..'F') ;
572       
573fragment
574Digit
575        : ('0'..'9') ;
576
577LINE_COMMENT
578    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
579    | '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
580    ;
581   
582WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;
583
Note: See TracBrowser for help on using the repository browser.