简体   繁体   中英

How to integrate the generated lexer/parser from Antlr4 into my java project

please bear with me I'm not a coding expert.

I built a grammar in ANTLR4 using ANTRWorks 2. I tested the grammar with various teststrings and it works fine within there. Now what I'm having trouble with is using the generated lexer and parser in my own code. As code generation target I'm using Java.

Here is the code I'm trying:

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());  

The Output of that is just "query", which is my starting rule. I would expect something like the output from ANTLRworks: "(query (quant_expr query ( (match std::map . find ( (cm x) ) == (cm (numeral 256))) ) : (query (qexpr bla))))" Here is the tree visually: http://puu.sh/94Nlx/00dc35bb05.png

Which methods do I have to call to get the proper syntax tree as output?

Here is the generated Parser for reference: http://pastebin.com/Lb34TyRW and the grammar:

// 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
        ;

Apart from the fact that Java Classes should start with an uppercase letter (so you should rename your grammar, so it starts with an uppercase letter) your last line should be

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

to print the tree. Otherwise the tree doesnÄt know which parser to use and only outputs what you described.

EDIT

When naming your grammar PQLC the following code

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
    }
}

produces this output with ANTLR v4.2 at my machine:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM