1header 2{ 3 using TokenStreamRewriteEngine = antlr.TokenStreamRewriteEngine; 4 using TokenWithIndex = antlr.TokenWithIndex; 5} 6 7options 8{ 9 language = "CSharp"; 10} 11 12class TinyCParser extends Parser; 13 14options 15{ 16 //importVocab=TinyC; // use vocab generated by lexer 17} 18 19{ 20 TokenStreamRewriteEngine engine; 21 22 public TinyCParser(TokenStreamRewriteEngine lexer) : this(lexer, 1) 23 { 24 engine = lexer; 25 } 26} 27 28program 29 : ( declaration )* EOF 30 ; 31 32declaration 33 : (globalVariable) => globalVariable 34 | function 35 ; 36 37declarator 38 : id:ID 39 | STAR id2:ID 40 ; 41 42variable 43 : type declarator SEMI 44 ; 45 46/** Convert "int foo;" into "extern int foo;" */ 47globalVariable 48 : {engine.insertBefore(LT(1), "extern ");} 49 variable 50 ; 51 52/** Convert "int foo() {...}" into "extern int foo();" */ 53function 54{ 55 int rcurly = 0; 56} 57 : {engine.insertBefore(LT(1), "extern ");} 58 type id:ID LPAREN 59 (formalParameter (COMMA formalParameter)*)? 60 RPAREN 61 block[true] 62 ; 63 64formalParameter 65 : type declarator 66 ; 67 68type: "int" | "char" | ID ; 69 70block[bool functionLevel] 71 : a:LCURLY ( statement )* b:RCURLY 72 { 73 if ( functionLevel ) 74 { 75 int prevTokenIndex = ((TokenWithIndex) a).getIndex()-1; 76 TokenWithIndex prevToken = engine.getToken(prevTokenIndex); 77 if ( prevToken.Type == RPAREN ) 78 { 79 engine.replace(a, b, ";"); 80 } 81 else 82 { 83 engine.replace(prevToken, b, ";"); // replace whitespace too 84 } 85 } 86 } 87 ; 88 89statement 90 : (variable)=>variable 91 | expr SEMI 92 | "if" LPAREN expr RPAREN statement 93 ( "else" statement )? 94 | "while" LPAREN expr RPAREN statement 95 | block[false] 96 ; 97 98expr: assignExpr 99 ; 100 101assignExpr 102 : aexpr (ASSIGN assignExpr)? 103 ; 104 105aexpr 106 : mexpr (PLUS mexpr)* 107 ; 108 109mexpr 110 : atom (STAR atom)* 111 ; 112 113atom: ID 114 | INT 115 | CHAR_LITERAL 116 | STRING_LITERAL 117 ; 118 119 120 121class TinyCLexer extends Lexer; 122 123options 124{ 125 k = 2; 126 charVocabulary = '\3'..'\377'; 127} 128 129WS : (' ' 130 | '\t' 131 | '\n' {newline();} 132 | '\r')+ 133 ; 134 135SL_COMMENT : 136 "//" 137 (~'\n')* '\n' 138 { $setType(Token.SKIP); newline(); } 139 ; 140 141ML_COMMENT 142 : "/*" 143 ( { LA(2)!='/' }? '*' 144 | '\n' { newline(); } 145 | ~('*'|'\n') 146 )* 147 "*/" 148 { $setType(Token.SKIP); } 149 ; 150 151 152LPAREN 153 : '(' 154 ; 155 156RPAREN 157 : ')' 158 ; 159 160LCURLY: '{' 161 ; 162 163RCURLY: '}' 164 ; 165 166STAR: '*' 167 ; 168 169PLUS: '+' 170 ; 171 172ASSIGN 173 : '=' 174 ; 175 176SEMI: ';' 177 ; 178 179COMMA 180 : ',' 181 ; 182 183CHAR_LITERAL 184 : '\'' (options {greedy=false;}:.)* '\'' 185 ; 186 187STRING_LITERAL 188 : '"' (options {greedy=false;}:.)* '"' 189 ; 190 191protected 192DIGIT 193 : '0'..'9' 194 ; 195 196INT : (DIGIT)+ 197 ; 198 199ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* 200 ; 201 202 203