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

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

v0.6.2
Made if-error compatible with python/pablo.
Cleaned up instruction printing and pythonating.
Fixed bug in copying ConditionASTN.

File size: 14.0 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                        int length = $m.text.length();
296                        $message = $m.text.substring(2, length-2);
297                        $falseTree = null;
298                        $trueTree = null;
299                }
300        ;
301       
302condition returns [AST asTree]
303        : e=bExpression c=conditionIndicator {
304                                int constant = $c.zeroes ? 0 : -1;
305                                $asTree = new ConditionASTN(constant, $c.complemented, $e.asTree);
306                        }
307        ;
308       
309conditionIndicator returns [boolean zeroes, boolean complemented]
310        : 'allzero' {
311                        $zeroes = true;
312                        $complemented = false;
313                }
314        | 'allone'  {
315                        $zeroes = false;
316                        $complemented = false;
317                }
318        | 'not' ci=conditionIndicator {
319                        $zeroes = $ci.zeroes;
320                        $complemented = !($ci.complemented);
321                }       
322        ;
323       
324bExpression returns [AST asTree]
325        : b=bExpression8 {
326                        $asTree = $b.asTree;
327                }
328        ;
329
330bExpression8 returns [AST asTree]
331        : b7 = bExpression7  {
332                                $asTree = $b7.asTree;
333                        }
334                (op=('+>'|'<>') b7b=bExpression7 {
335                                if($op.text.equals("+>")) {
336                                        $asTree = ScanThroughASTB.make($asTree, $b7b.asTree);
337                                }
338                                else {
339                                        $asTree = SpanASTB.make($asTree, $b7b.asTree);
340                                }
341                        }
342                )*
343         ;
344bExpression7 returns [AST asTree]       
345        // right-associative? left-associative?
346        : b6 = bExpression6 {
347                                $asTree = $b6.asTree;
348                        }
349                ('?' b7t=bExpression7 ':' b7f=bExpression6 {
350                                $asTree = SelectionASTB.make($asTree, $b7t.asTree, $b7f.asTree);
351                        }
352                )*
353        ;
354       
355bExpression6 returns [AST asTree]
356@init{
357        List<AST> bExpr5s = new ArrayList<AST>();
358}
359        : b5 = bExpression5  {
360                                bExpr5s.add(OrASTB.singleChild($b5.asTree));
361                        }
362                ((op='|' | op='^') b5=bExpression5 {
363                                if($op.text.equals("|")) {
364                                        bExpr5s.add(OrASTB.singleChild($b5.asTree));
365                                }
366                                else if($op.text.equals("^")) {
367                                        bExpr5s.add(XorASTB.singleChild($b5.asTree));
368                                }
369                                else {
370                                        System.err.println("bad or-operation in bExpression6: " + $op.text);
371                                }
372                        }
373                )* {
374                        $asTree = FalseLiteralASTB.make();
375                        for(AST expr: bExpr5s) {
376                                if(expr instanceof OrASTB) {
377                                        $asTree = OrASTB.make($asTree, expr.getChild(0));
378                                }
379                                else {
380                                        $asTree = XorASTB.make($asTree, expr.getChild(0));
381                                }
382                        }
383                }
384        ;
385       
386bExpression5 returns [AST asTree]
387@init{
388        List<AST> bExpr4s = new ArrayList<AST>();
389}
390        : b4=bExpression4 {bExpr4s.add($b4.asTree);}
391                ('&' b4=bExpression4 {bExpr4s.add($b4.asTree);} )* {
392                        $asTree = TrueLiteralASTB.make();
393                        for(AST expr: bExpr4s) {
394                                $asTree = AndASTB.make($asTree, expr);
395                        }
396                }
397//      | bExpression4
398        ;
399       
400bExpression4 returns [AST asTree]
401//      : bExpression3 (('+'^|'-'^) bExpression3)*     
402        : bExpression3 {$asTree = $bExpression3.asTree;}
403        ;
404       
405bExpression3 returns [AST asTree]
406        : bExpression2 {$asTree = $bExpression2.asTree;}
407        ;
408       
409bExpression2 returns [AST asTree]
410        : '~' expr = bExpression2 {
411                        $asTree = NotASTB.make($expr.asTree);
412          }
413        | '>' expr = bExpression2 {
414                        $asTree = ShiftASTB.make($expr.asTree, 1);
415          }
416        | bExpression1 {$asTree = $bExpression1.asTree;}
417        ;
418       
419bExpression1 returns [AST asTree]
420        : s = SequenceLiteral {
421                        PebbleToken token = (PebbleToken)s;//.token;
422                        SequenceTokenData seqData = token.sequenceData();
423                        $asTree = SequenceASTB.make(seqData);
424          }
425    | c = CharClassToken  {
426                        PebbleToken token = (PebbleToken)c;//.token;
427                        CharClassTokenData ccData = token.charClassData();
428                        ccData.seal();
429                        $asTree = CharClassASTB.make(ccData);
430                        if(ccData.isComplemented()) {
431                                $asTree = NotASTB.make($asTree);
432                        }
433      }
434    | i = Identifier {
435                        $asTree = VariableASTB.make($i.text);
436      }
437    | n = IntegerConstant {
438                int value = Integer.parseInt($n.text);
439                $asTree = ConstantASTB.make(value);
440        }
441    | 'false' {
442                $asTree = FalseLiteralASTB.make();
443        }
444    | 'true' {
445                $asTree = TrueLiteralASTB.make();
446        }
447    | '(' bExpression ')' {
448                        $asTree = $bExpression.asTree;
449      }
450    ;
451
452
453///////////////////////////////////////////////////////////////////////////////
454//
455//  Tokens
456//
457///////////////////////////////////////////////////////////////////////////////
458
459StringConstant
460        : '<<' Non_RAngle* '>>'
461        ;
462
463Identifier
464        :       IdentiFrag ;
465       
466IntegerConstant
467        :       Digit* | '-' Digit*;
468
469SequenceLiteral
470@init {
471        SequenceTokenData seqData = new SequenceTokenData();
472}
473@after {
474        // do this after, as CharClassFrag plays with tokenData, as well.
475        tokenData = seqData;
476}
477
478    :   '"' ( options {greedy = false;}:
479                  (
480                     esc = EscapeSequence {
481//                      System.out.println("seq escaped: " + $esc.text);
482//                      seqData.add(ElementType.CHAR, ""+$esc.text.charAt(1));
483                        seqData.add(SequenceTokenData.singleCharacterClassData((char)(util.StringUtils.escapeValue($esc.text))));
484                     }
485//                |  dot = ColonedIdentifier {
486//                              // System.out.println("seq dotted: " + $dot.text);
487//                      seqData.add(trimDots($dot.text));
488//                       }
489                  |  cc = CharClassFrag {
490                                // System.out.println("seq cclass: " + tokenData.toString());
491                                ((CharClassTokenData)tokenData).seal();
492                        seqData.add((CharClassTokenData)tokenData);
493                        tokenData = null;
494                         }
495                  |  oth = SequenceOtherChar {
496//                      System.out.println("seq other: " + $oth.text);
497//                      seqData.add(ElementType.CHAR, ""+$oth.text);
498                        seqData.add(SequenceTokenData.singleCharacterClassData($oth.text.charAt(0)));
499                     }
500                  )*
501            )
502        '"'
503    ;
504fragment
505SequenceOtherChar:      ~('"'|'\\'|'.'|'[') ;
506   
507CharClassToken: CharClassFrag ;
508
509fragment   
510CharClassFrag
511@init {
512        CharClassTokenData charClassData = new CharClassTokenData();
513        tokenData = charClassData;
514}
515        :       '['
516                        ('^' {charClassData.setComplemented();}) ?
517                (
518                          esc=EscapeSequence {
519                                // System.out.println("CC escaped: " + $esc.text.charAt(1));
520                                charClassData.addChar((char)(util.StringUtils.escapeValue($esc.text)));
521                          }
522//                      | col=ColonedIdentifier {
523//                              // System.out.println("CC dot: " + $dot.text);
524//                              charClassData.addStream(trimDots($col.text));
525//                        }
526                        | non=Non_Escape_RB_Caret  {
527                                // System.out.println("CC non: " + $non.text);
528                                charClassData.addChar($non.text.charAt(0));
529                          }
530                        )*
531                ']'
532        ;
533
534
535
536fragment
537ColonedIdentifier
538        :       ':' IdentiFrag ':'
539        ;
540fragment
541IdentiFrag
542//              WARNING!  dot ('.') hacked into here for allowing structure-reference!
543//                                      clean it up!
544//              '$' included for array indexing.
545        :       ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.'|'$')*
546        ;
547fragment
548Non_Escape_RB_Colon_Caret
549        :       ~('\\' | ']' | ':' | '^')
550        ;
551fragment
552Non_Escape_RB_Caret
553        :       ~('\\' | ']' | '^')
554        ;
555
556fragment
557Non_RAngle:     ~('>') ;
558       
559fragment
560EscapeSequence
561    :   '\\' ('a'..'w'| 'y'..'z'| 'A'..'Z' | '_' | '\"' | '\'' | '\\' | '[' | ']' | '.'| '-' | '^')
562        | HexEscape
563    ;
564   
565fragment
566HexEscape
567    :   '\\' 'x' HexDigit HexDigit
568    ;
569 
570fragment
571HexDigit
572        : ('0'..'9'|'a'..'f'|'A'..'F') ;
573       
574fragment
575Digit
576        : ('0'..'9') ;
577
578LINE_COMMENT
579    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
580    | '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
581    ;
582   
583WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;
584
Note: See TracBrowser for help on using the repository browser.