Skip to content

Instantly share code, notes, and snippets.

@sanxiyn
Created February 26, 2011 08:48
Show Gist options
  • Save sanxiyn/845066 to your computer and use it in GitHub Desktop.
Save sanxiyn/845066 to your computer and use it in GitHub Desktop.
ANTLR3 C sample
#!/bin/sh
antlr3 test.g
g++ *.cc *.c -o t -lantlr3c
a = 1 + 2 * 3;
b = (1 + 2) * 3;
a * b;
#include <map>
#include <string>
#include "testLexer.h"
#include "testParser.h"
std::map<std::string,int> table;
int eval(pANTLR3_BASE_TREE expr) {
int type = expr->getType(expr);
if (type == PLUS) {
pANTLR3_BASE_TREE left = (pANTLR3_BASE_TREE)expr->getChild(expr, 0);
pANTLR3_BASE_TREE right = (pANTLR3_BASE_TREE)expr->getChild(expr, 1);
return eval(left) + eval(right);
} else if (type == MUL) {
pANTLR3_BASE_TREE left = (pANTLR3_BASE_TREE)expr->getChild(expr, 0);
pANTLR3_BASE_TREE right = (pANTLR3_BASE_TREE)expr->getChild(expr, 1);
return eval(left) * eval(right);
} else if (type == ID) {
std::string name((const char *)expr->getText(expr)->chars);
return table[name];
} else if (type == DIGIT) {
pANTLR3_UINT8 value = expr->getText(expr)->chars;
return atoi((const char *)value);
}
}
int main() {
pANTLR3_UINT8 filename = (pANTLR3_UINT8)"test";
pANTLR3_INPUT_STREAM input = antlr3AsciiFileStreamNew(filename);
ptestLexer lexer = testLexerNew(input);
pANTLR3_COMMON_TOKEN_STREAM stream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
ptestParser parser = testParserNew(stream);
testParser_translation_unit_return unit = parser->translation_unit(parser);
pANTLR3_BASE_TREE tree = unit.tree;
for (int i = 0; i < tree->getChildCount(tree); i++) {
pANTLR3_BASE_TREE stat = (pANTLR3_BASE_TREE)tree->getChild(tree, i);
if (stat->getType(stat) == ASSIGN) {
pANTLR3_BASE_TREE id = (pANTLR3_BASE_TREE)stat->getChild(stat, 0);
pANTLR3_BASE_TREE expr = (pANTLR3_BASE_TREE)stat->getChild(stat, 1);
std::string name((const char *)id->getText(id)->chars);
int value = eval(expr);
table[name] = value;
} else {
int value = eval(stat);
printf("%d\n", value);
}
}
return 0;
}
grammar test;
options {
language = C;
k = 2;
output = AST;
}
translation_unit:
statement+ EOF -> statement+;
statement:
stat_assign NL -> stat_assign |
expression NL -> expression;
expression:
expr_add;
stat_assign:
identifier ASSIGN expression -> ^(ASSIGN identifier expression);
expr_add:
expr_mul (PLUS expr_add)? -> ^(PLUS expr_mul expr_add);
expr_mul:
expr_primary (MUL expr_mul)? -> ^(MUL expr_primary expr_mul);
expr_primary:
constant |
identifier |
'(' expression ')' -> expression;
constant: DIGIT;
identifier: ID;
DIGIT: (('1'..'9') ('0'..'9')*) | '0';
ID: ('a'..'z') ('a'..'z' | '0'..'9')*;
WS: (' ' | '\n')+ {$channel = HIDDEN;};
NL: ';';
ASSIGN: '=';
PLUS: '+';
MUL: '*';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment