用ANTLR3实现规则解析----1-安装

来源:互联网 发布:手机挖矿软件 编辑:程序博客网 时间:2024/05/22 09:49

1、安装antlr3.4 运行环境

  首先从antlr官网下载处,获取了libantlr3c-3.4.tar.gz下载包

 按照install文件的说明的安装步骤执行安装

  #1 ./configure

  #2 make;  这一步报错

/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory

     /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/stddef.h:214: error: duplicate 'unsigned'/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/stddef.h:214: error: two or more data types in declaration specifiers

      原因:我的系统是64位的,所以第一步应该为 ./configure  --enable-64bit

  #3 make install

2、安装antlr tool

    #1、先安装java

    #2、cd  /usr/local/lib

         wget   antlr-3.5-complete.jar

        export CLASSPATH=/usr/local/lib/antlr-3.5-complete.jar:$CLASSPATH

    #3、运行:java org.antlr.Tool

2、antlr上手--hello world

   http://www.antlr.org/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3

  上有antlr3的例子,这里我们用c++例子,这是一个简单的 计算器,支持 + - * /

   #1、grammar文件 保存为

          ExprCppTree,g 文件
grammar ExprCppTree;options {    language = C;    output = AST;    ASTLabelType=pANTLR3_BASE_TREE;}@header {    #include <assert.h>}// The suffix '^' means make it a root.// The suffix '!' means ignore it.expr: multExpr ((PLUS^ | MINUS^) multExpr)*    ;PLUS: '+';MINUS: '-';multExpr    : atom (TIMES^ atom)*    ;TIMES: '*';atom: INT    | ID    | '('! expr ')'!    ;stmt: expr NEWLINE -> expr  // tree rewrite syntax    | ID ASSIGN expr NEWLINE -> ^(ASSIGN ID expr) // tree notation    | NEWLINE ->   // ignore    ;ASSIGN: '=';prog    : (stmt {pANTLR3_STRING s = $stmt.tree->toStringTree($stmt.tree);             assert(s->chars);             printf(" tree \%s\n", s->chars);            }        )+    ;ID: ('a'..'z'|'A'..'Z')+ ;INT: '~'? '0'..'9'+ ;NEWLINE: '\r'? '\n' ;WS : (' '|'\t')+ {$channel = HIDDEN;};


  #2、运行:java org.antlr.Tool  ExprCppTree,g 
 #3、加入main.c
#include "ExprCppTreeLexer.h"#include "ExprCppTreeParser.h"#include <cassert>#include <map>#include <string>#include <iostream>using std::map;using std::string;using std::cout;class ExprTreeEvaluator {    map<string,int> memory;public:    int run(pANTLR3_BASE_TREE);};pANTLR3_BASE_TREE getChild(pANTLR3_BASE_TREE, unsigned);const char* getText(pANTLR3_BASE_TREE tree);int main(int argc, char* argv[]){  pANTLR3_INPUT_STREAM input;  pExprCppTreeLexer lex;  pANTLR3_COMMON_TOKEN_STREAM tokens;  pExprCppTreeParser parser;  assert(argc > 1);  input = antlr3FileStreamNew((pANTLR3_UINT8)argv[1],ANTLR3_ENC_8BIT);  lex = ExprCppTreeLexerNew(input);  tokens = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT,                                            TOKENSOURCE(lex));  parser = ExprCppTreeParserNew(tokens);  ExprCppTreeParser_prog_return r = parser->prog(parser);  pANTLR3_BASE_TREE tree = r.tree;  ExprTreeEvaluator eval;  int rr = eval.run(tree);  cout << "Evaluator result: " << rr << '\n';  parser->free(parser);  tokens->free(tokens);  lex->free(lex);  input->close(input);  return 0;}int ExprTreeEvaluator::run(pANTLR3_BASE_TREE tree){    pANTLR3_COMMON_TOKEN tok = tree->getToken(tree);    if(tok) {        switch(tok->type) {        case INT: {            const char* s = getText(tree);            if(s[0] == '~') {                return -atoi(s+1);            }            else {                return atoi(s);            }        }        case ID: {            string var(getText(tree));            return memory[var];        }        case PLUS:            return run(getChild(tree,0)) + run(getChild(tree,1));        case MINUS:            return run(getChild(tree,0)) - run(getChild(tree,1));        case TIMES:            return run(getChild(tree,0)) * run(getChild(tree,1));        case ASSIGN: {            string var(getText(getChild(tree,0)));            int val = run(getChild(tree,1));            memory[var] = val;            return val;        }        default:            cout << "Unhandled token: #" << tok->type << '\n';            return -1;        }    }    else {        int k = tree->getChildCount(tree);        int r = 0;        for(int i = 0; i < k; i++) {            r = run(getChild(tree, i));        }        return r;    }}pANTLR3_BASE_TREE getChild(pANTLR3_BASE_TREE tree, unsigned i){    assert(i < tree->getChildCount(tree));    return (pANTLR3_BASE_TREE) tree->getChild(tree, i);}const char* getText(pANTLR3_BASE_TREE tree){    return (const char*) tree->getText(tree)->chars;}


 #4、编译:g++ -g -Wall *.c -o test -I. -L /usr/local/lib  -lantlr3c
#5、运行
        ./test a(a为文件,可简单写入 1+1)
         tree (+ 1 1)        Evaluator result: 2
原创粉丝点击