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