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