如何将生成的词法分析器/解析器从Antlr4集成到我的java项目中

时间:2014-05-28 14:04:46

标签: java parsing antlr4

请耐心等待我,我不是编码专家。

我使用ANTRWorks 2在ANTLR4中构建了一个语法。我使用各种测试字符串测试了语法,并且在那里工作正常。现在我遇到的麻烦就是在我自己的代码中使用生成的词法分析器和解析器。作为代码生成目标,我使用Java。

以下是我尝试的代码:

String s = "query(std::map .find(x) == y): bla";
ANTLRInputStream input = new ANTLRInputStream(s);
TokenStream tokens = new CommonTokenStream(new pqlcLexer(input)); 

pqlcParser parser = new pqlcParser(tokens); 
ParseTree tree = parser.query();
System.out.println(tree.toStringTree());  

输出只是"查询",这是我的起始规则。我希望有类似ANTLRworks的输出: "(查询(quant_expr查询((匹配std :: map。查找((cm x))==(cm(数字256)))):(查询(qexpr bla))))" 这是视觉上的树:http://puu.sh/94Nlx/00dc35bb05.png

我必须调用哪些方法才能将正确的语法树作为输出?

以下是生成的Parser供参考:http://pastebin.com/Lb34TyRW和语法:

// Lexer

//Schlüsselwörter
EXISTS: 'exists';
REDUCE: 'reduce';
QUERY: 'query';
INT: 'int';
DOUBLE: 'double';
CONST: 'const';
STDVECTOR: 'std::vector';
STDMAP: 'std::map';
STDSET: 'std::set';

INTEGER_LITERAL  : (DIGIT)+ ;
fragment DIGIT: '0'..'9';
DOUBLE_LITERAL : DIGIT '.' DIGIT+;

LPAREN          : '(';
RPAREN          : ')';
LBRACK          : '[';
RBRACK          : ']';
DOT             : '.';
EQUAL           : '==';
LE              : '<=';
GE              : '>=';
GT              : '>';
LT              : '<';
ADD             : '+';
MUL             : '*';
AND             : '&&';
COLON           : ':';

IDENTIFIER    :   JavaLetter JavaLetterOrDigit*;
fragment JavaLetter    :   [a-zA-Z$_]; // these are the "java letters" below 0xFF
fragment JavaLetterOrDigit    :   [a-zA-Z0-9$_]; // these are the "java letters or digits" below 0xFF
WS  
    :  [ \t\r\n\u000C]+ -> skip  
    ;
COMMENT
    :   '/*' .*? '*/' -> skip
    ;

LINE_COMMENT
    :   '//' ~[\r\n]* -> skip
    ;


// Parser

//start_rule: query;

query :
      quant_expr
      | qexpr+
      | IDENTIFIER // order IDENTIFIER and qexpr+?
      | numeral
      //| c_expr TODO

      ;

c_type : INT | DOUBLE | CONST;
bin_op: AND | ADD | MUL | EQUAL | LT | GT | LE| GE;


qexpr:
         LPAREN query RPAREN bin_op_query? 
         // query bin_op query
         | IDENTIFIER  bin_op_query? // copied from query to resolve left recursion problem
         | numeral bin_op_query?  // ^
         | quant_expr bin_op_query? // ^
           // query.find(query)
         | IDENTIFIER  find_query? // copied from query to resolve left recursion problem
         | numeral find_query?  // ^
         | quant_expr find_query?
           // query[query]
          | IDENTIFIER  array_query? // copied from query to resolve left recursion problem
         | numeral array_query?  // ^
         | quant_expr array_query?

     // | qexpr bin_op_query // bad, resolved by quexpr+ in query 
     ;

bin_op_query: bin_op query bin_op_query?; // resolve left recursion of query bin_op query

find_query: '.''find' LPAREN query RPAREN;
array_query: LBRACK query RBRACK;

quant_expr:
    quant id ':' query
          | QUERY LPAREN match RPAREN ':' query
          | REDUCE LPAREN IDENTIFIER RPAREN id ':' query
    ;

match:
         STDVECTOR LBRACK id RBRACK EQUAL cm
     | STDMAP '.''find' LPAREN cm RPAREN EQUAL cm
     | STDSET '.''find' LPAREN cm RPAREN
     ;

cm:
    IDENTIFIER
  | numeral
  // | c_expr TODO
  ;

quant :
          EXISTS;

id :
     c_type IDENTIFIER
     | IDENTIFIER // Nach Seite 2 aber nicht der Übersicht. Laut übersicht id -> aber dann wäre Regel 1 ohne +
   ;

numeral :
            INTEGER_LITERAL
        | DOUBLE_LITERAL
        ;

1 个答案:

答案 0 :(得分:6)

除了Java Classes应该以大写字母开头(因此你应该重命名你的语法,所以它以大写字母开头),你的最后一行应该是

System.out.println(tree.toStringTree(parser));

打印树。否则,树不知道要使用哪个解析器,只输出您描述的内容。

修改

在命名语法PQLC时使用以下代码

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

public class Test {
    public static void main(String[] args) throws Exception {
        String query = "query(std::map .find(x) == y): bla";
        ANTLRInputStream input = new ANTLRInputStream(query);
        PQLCLexer lexer = new PQLCLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        PQLCParser parser = new PQLCParser(tokens);
        ParseTree tree = parser.query(); // begin parsing at query rule
        System.out.println(tree.toStringTree(parser)); // print LISP-style tree
    }
}

在我的机器上使用ANTLR v4.2生成此输出:

(query (quant_expr query ( (match std::map . find ( (cm x) ) == (cm y)) ) : (query (qexpr bla))))