1grammar t018llstar; 2 3options { 4 language = Python3; 5} 6 7@header { 8from io import StringIO 9} 10 11@init { 12self.output = StringIO() 13} 14 15program 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 */ 28declaration 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 36variable 37 : type declarator ';' 38 ; 39 40declarator 41 : ID 42 ; 43 44functionHeader returns [name] 45 : type ID '(' ( formalParameter ( ',' formalParameter )* )? ')' 46 {$name = $ID.text} 47 ; 48 49formalParameter 50 : type declarator 51 ; 52 53type 54 : 'int' 55 | 'char' 56 | 'void' 57 | ID 58 ; 59 60block 61 : '{' 62 variable* 63 stat* 64 '}' 65 ; 66 67stat: forStat 68 | expr ';' 69 | block 70 | assignStat ';' 71 | ';' 72 ; 73 74forStat 75 : 'for' '(' assignStat ';' expr ';' assignStat ')' block 76 ; 77 78assignStat 79 : ID '=' expr 80 ; 81 82expr: condExpr 83 ; 84 85condExpr 86 : aexpr ( ('==' | '<') aexpr )? 87 ; 88 89aexpr 90 : atom ( '+' atom )* 91 ; 92 93atom 94 : ID 95 | INT 96 | '(' expr ')' 97 ; 98 99ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 100 ; 101 102INT : ('0'..'9')+ 103 ; 104 105WS : ( ' ' 106 | '\t' 107 | '\r' 108 | '\n' 109 )+ 110 {$channel=HIDDEN} 111 ; 112