1 grammar t018llstar; 2 3 options { 4 language = Python; 5 } 6 7 @header { 8 from cStringIO import StringIO 9 } 10 11 @init { 12 self.output = StringIO() 13 } 14 15 program 16 : declaration+ 17 ; 18 19 /** In this rule, the functionHeader left prefix on the last two 20 * alternatives is not LL(k) for a fixed k. However, it is 21 * LL(*). The LL(*) algorithm simply scans ahead until it sees 22 * either the ';' or the '{' of the block and then it picks 23 * the appropriate alternative. Lookhead can be arbitrarily 24 * long in theory, but is <=10 in most cases. Works great. 25 * Use ANTLRWorks to see the lookahead use (step by Location) 26 * and look for blue tokens in the input window pane. :) 27 */ 28 declaration 29 : variable 30 | functionHeader ';' 31 {self.output.write($functionHeader.name+" is a declaration\n")} 32 | functionHeader block 33 {self.output.write($functionHeader.name+" is a definition\n")} 34 ; 35 36 variable 37 : type declarator ';' 38 ; 39 40 declarator 41 : ID 42 ; 43 44 functionHeader returns [name] 45 : type ID '(' ( formalParameter ( ',' formalParameter )* )? ')' 46 {$name = $ID.text} 47 ; 48 49 formalParameter 50 : type declarator 51 ; 52 53 type 54 : 'int' 55 | 'char' 56 | 'void' 57 | ID 58 ; 59 60 block 61 : '{' 62 variable* 63 stat* 64 '}' 65 ; 66 67 stat: forStat 68 | expr ';' 69 | block 70 | assignStat ';' 71 | ';' 72 ; 73 74 forStat 75 : 'for' '(' assignStat ';' expr ';' assignStat ')' block 76 ; 77 78 assignStat 79 : ID '=' expr 80 ; 81 82 expr: condExpr 83 ; 84 85 condExpr 86 : aexpr ( ('==' | '<') aexpr )? 87 ; 88 89 aexpr 90 : atom ( '+' atom )* 91 ; 92 93 atom 94 : ID 95 | INT 96 | '(' expr ')' 97 ; 98 99 ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 100 ; 101 102 INT : ('0'..'9')+ 103 ; 104 105 WS : ( ' ' 106 | '\t' 107 | '\r' 108 | '\n' 109 )+ 110 {$channel=HIDDEN} 111 ; 112