Need to parse SQL query to C++ code in project, so I had to learn antlr these days.
Let’s write a small sample file “Calc.g” for antlr3:

grammar Calc;
options {
    language = Cpp;
}
@lexer::header {
    #include 
    #include 
    #include 
    using namespace std;
}
@lexer::traits {
  class CalcLexer;
  class CalcParser;
  typedef antlr3::Traits CalcLexerTraits;
}
@parser::header {
  #include "./CalcLexer.hpp"
}
@parser::traits {
  typedef CalcLexerTraits CalcParserTraits;
}
@parser::context {
  typedef std::map StringMap;
  StringMap var_map;
}
prog:   (stat)+ ;
stat:   expr NEWLINE        { cout << $expr.value << endl; }
    |   ID '=' expr NEWLINE { string id = $ID.text;
                              var_map[id] = $expr.value;
                            }
    |   NEWLINE
    ;
expr returns [int value]
    :   a=multiExpr {$value = $a.value;}
        ( '+' b=multiExpr {$value += $b.value;}
        | '-' c=multiExpr {$value -= $c.value;}
        )*
    ;
multiExpr returns [int value]
    :   a=atom {$value = $a.value;}
        ('*' b=atom {$value *= $b.value;}
        )*
    ;
atom returns [int value]
    :   INT { $value = atoi($INT.text.c_str()); }
    |   ID  { int v = var_map[$ID.text];
              $value = v;
            }
    |   '(' expr ')' {$value = $expr.value;}
    ;
ID  :   ('a'..'z')+ ;
INT :   ('0'..'9')+ ;
NEWLINE: '\r'? '\n' ;
WS  :   (' '|'\t'|'\n'|'\r')+ {skip();} ;

Then add "antlr-3.5.2-complete.jar" (run "mvn package" on source code path of antlr3 will generate this jar) to CLASSPATH and run:

java org.antlr.Tool Calc.g

It will generate many code files: CalcLexer.[hpp/cpp], CalcParser.[hpp/cpp], Calc.tokens. Now we could compile all generated C++ codes:

g++ CalcLexer.cpp CalcParser.cpp Test.cpp -I$(ANTLR3_SRC_PATH)/runtime/Cpp/include/ -I./ -o Test

("ANTLR3_SRC_PATH" is where the antlr3 source code are
But this step lead compiler errors for g++:

CalcParser.cpp: In member function ‘void CalcParser::stat()’:
CalcParser.cpp:436:67: error: invalid conversion from ‘const CommonTokenType* {aka const antlr3::CommonToken >*}’ to ‘antlr3::Traits::CommonTokenType* {aka antlr3::CommonToken >*}’ [-fpermissive]
                  ID2 =  this->matchToken(ID, &FOLLOW_ID_in_stat106);
                                                                   ^
CalcParser.cpp: In member function ‘int CalcParser::atom()’:
CalcParser.cpp:836:70: error: invalid conversion from ‘const CommonTokenType* {aka const antlr3::CommonToken >*}’ to ‘antlr3::Traits::CommonTokenType* {aka antlr3::CommonToken >*}’ [-fpermissive]
                  INT4 =  this->matchToken(INT, &FOLLOW_INT_in_atom276);
                                                                      ^
CalcParser.cpp:854:67: error: invalid conversion from ‘const CommonTokenType* {aka const antlr3::CommonToken >*}’ to ‘antlr3::Traits::CommonTokenType* {aka antlr3::CommonToken >*}’ [-fpermissive]
                  ID5 =  this->matchToken(ID, &FOLLOW_ID_in_atom288);
                                                                   ^

The reason is 'ID' and 'INT' should be declare as "const CommonTokenType*", rather than "CommonTokenType*". The fix has already be commited to antlr3 and be contained in master branch of git tree. Therefore I checkout the master branch of antlr3 instead of "3.5.2" tag, re-package the jar of antlr3, re-generate the code for "Calc.g", and the compiler errors disappeared.
The target executable file is "Test", now we can use it to parse our "code":

echo "a=3
b=4
3+a*b" | ./Test
15

The result '15' is correct.