A Simple Example of ANTLR4 and C++
本篇文章着重介绍 C++ 下如何使用 ANTLR4 ,不会深究 ANTLR4 的语法。
定义语法文件
参考 MySqlLexer.g4 和 MySqlParser.g4 定义一个非常简单的加减运算:
1 2 3 4 5 6 7 8 // ArithmeticLexer.g4 lexer grammar ArithmeticLexer; options { language=Cpp; } PLUS: '+'; MINUS: '-'; DEC_DIGIT: [0-9]+;
1 2 3 4 5 6 7 8 9 // ArithmeticParser.g4 parser grammar ArithmeticParser; options { tokenVocab=ArithmeticLexer; language=Cpp; } expression : left=DEC_DIGIT PLUS right=DEC_DIGIT | left=DEC_DIGIT MINUS right=DEC_DIGIT ;
编译 ANTLR Cpp runtime
ANTLR4 不提供 Linux 下的二进制文件,需要从 ANTLR4 源代码 自行编译。
编译依赖: build-essential make cmake g++ git uuid-dev pkg-config
1 2 3 4 cd antlr/runtime/Cppmkdir build && cd build cmake .. make -j20 && make install
编译头文件放于 /usr/local/include/antlr4-runtime ,链接库放于 /usr/local/lib 。
若不想安装,也可执行 make package 命令将头文件和链接库打包到 LIBANTLR4-4.8-Linux.tar.gz 文件。
按 Listener 模式访问语法树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include "ANTLRInputStream.h" #include "CommonTokenStream.h" #include "generated/ArithmeticLexer.h" #include "generated/ArithmeticParser.h" #include "generated/ArithmeticParserBaseListener.h" #include "tree/ParseTreeWalker.h" #include <iostream> #include <string> class MyListener : public ArithmeticParserBaseListener { public : void exitExpression (ArithmeticParser::ExpressionContext* ctx) { int left = std::stoi (ctx->left->getText ()); int right = std::stoi (ctx->right->getText ()); if (ctx->PLUS () != nullptr ) { std::cout << left + right << std::endl; } else { std::cout << left - right << std::endl; } } };int main () { antlr4::ANTLRInputStream inputStream ("1+1" ) ; ArithmeticLexer lexer (&inputStream) ; antlr4::CommonTokenStream tokens (&lexer) ; ArithmeticParser parser (&tokens) ; MyListener listener; antlr4::tree::ParseTreeWalker::DEFAULT.walk (&listener, parser.expression ()); return 0 ; }
1 2 3 4 5 g++ -std=c++11 main.cpp \ $(find generated -type f -name "*.cpp" ) \ -I/usr/local/include/antlr4-runtime \ -L/usr/local/lib/ -Wl,-rpath=/usr/local/lib/ -lantlr4-runtime \ -o main
Reference
https://github.com/antlr/antlr4/blob/master/doc/cpp-target.md