简体   繁体   English

使生成的解析器在 Java 中为 ANTLR 4.8 工作

[英]Making generated parser work in Java for ANTLR 4.8

I've been having trouble getting my generated parser to work in Java for ANTLR 4.8.我一直无法让我生成的解析器在 ANTLR 4.8 的 Java 中工作。 There are other answers to this question, but it seems that ANTLR has changed things since 4.7 and all the other answers are before this change.这个问题还有其他答案,但似乎 ANTLR 自 4.7 以来发生了变化,所有其他答案都在此更改之前。 My code is:我的代码是:

    String formula = "(fm.a < fm.b) | (fm.a = fm.b)";
    CharStream input = CharStreams.fromString(formula);
    Antlr.LogicGrammerLexer lexer = new Antlr.LogicGrammerLexer(input);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    Antlr.LogicGrammerParser parser = new Antlr.LogicGrammerParser(tokens);
    ParseTree pt = new ParseTree(parser);

It appears to be reading in the formula correctly into the CharStream, but anything I try to do past that just isn't working at all.它似乎正在将公式正确地读入 CharStream,但是我过去尝试做的任何事情都根本不起作用。 For example, if I try to print out the parse tree, nothing will be printed.例如,如果我尝试打印解析树,则不会打印任何内容。 The following line will print out nothing:以下行将不打印任何内容:

    System.out.println(lexer._input.getText(new Interval(0, 100)));

Any advice appreciated.任何建议表示赞赏。

EDIT: added the grammar file:编辑:添加了语法文件:

grammar LogicGrammer;

logicalStmt: BOOL_EXPR | '('logicalStmt' '*LOGIC_SYMBOL' '*logicalStmt')';
BOOL_EXPR: '('IDENTIFIER' '*MATH_SYMBOL' '*IDENTIFIER')';
IDENTIFIER: CHAR+('.'CHAR*)*;
CHAR: 'a'..'z' | 'A'..'Z' | '1'..'9';
LOGIC_SYMBOL: '~' | '|' | '&';
MATH_SYMBOL: '<' | '≤' | '=' | '≥' | '>';

This line:这一行:

ParseTree pt = new ParseTree(parser);

is incorrect.是不正确的。 You need to call the start rule method on your parser object to get your parse tree您需要在解析器 object 上调用启动规则方法来获取解析树

Antlr.LogicGrammerParser parser = new Antlr.LogicGrammerParser(tokens);
ParseTree pt = parser.whateveryourstartruleis();

So far as printing out your input, generally fields starting with an _ (like _input ) are not intended for external use.就打印出您的输入而言,通常以_开头的字段(如_input )不适合外部使用。 Though I suspect the failure may be that you don't have 100 characters in your input stream, so the Interval is invalid.虽然我怀疑失败可能是您的输入 stream 中没有 100 个字符,所以Interval无效。 (I haven't tried it to see the exact failure) (我还没有尝试看到确切的失败)

I you include your grammar, one of us could easily attempt to generate and compile and, perhaps, be more specific.如果你包括你的语法,我们中的一个人可以很容易地尝试生成和编译,也许更具体。

The BOOL_EXPR shouldn't be a lexer rule. BOOL_EXPR不应该是词法分析器规则。 I suggest you do something like this instead:我建议你改为这样做:

grammar LogicGrammer;

parse
 : logicalStmt EOF
 ;

logicalStmt
 : logicalStmt LOGIC_SYMBOL logicalStmt
 | logicalStmt MATH_SYMBOL logicalStmt
 | '(' logicalStmt ')'
 | IDENTIFIER
 ;

IDENTIFIER
 : CHAR+ ( '.'CHAR+ )*
 ;

LOGIC_SYMBOL
 : [~|&]
 ;

MATH_SYMBOL
 : [<≤=≥>]
 ;

SPACE
 : [ \t\r\n] -> skip
 ;

fragment CHAR
 : [a-zA-Z1-9]
 ;

which can be tested by running the following code:可以通过运行以下代码进行测试:

String formula = "(fm.a < fm.b) | (fm.a = fm.b)";
LogicGrammerLexer lexer = new LogicGrammerLexer(CharStreams.fromString(formula));
LogicGrammerParser parser = new LogicGrammerParser(new CommonTokenStream(lexer));
ParseTree root = parser.parse();
System.out.println(root.toStringTree(parser));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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