我正在使用IntelliJ的antlr4插件为我正在处理的一个项目创建语法。在学习如何使用antlr的过程中,我查看了Github用户shmatov的简单antlr4计算器,如下所示。
grammar Calculator;
INT : [0-9]+;
DOUBLE : [0-9]+'.'[0-9]+;
PI : 'pi';
E : 'e';
POW : '^';
NL : '\n';
WS : [ \t\r]+ -> skip;
ID : [a-zA-Z_][a-zA-Z_0-9]*;
PLUS : '+';
EQUAL : '=';
MINUS : '-';
MULT : '*';
DIV : '/';
LPAR : '(';
RPAR : ')';
input
: plusOrMinus NL? EOF # Calculate
;
plusOrMinus
: plusOrMinus PLUS multOrDiv # Plus
| plusOrMinus MINUS multOrDiv # Minus
| multOrDiv # ToMultOrDiv
;
multOrDiv
: multOrDiv MULT pow # Multiplication
| multOrDiv DIV pow # Division
| pow # ToPow
;
pow
: unaryMinus (POW pow)? # Power
;
unaryMinus
: MINUS unaryMinus # ChangeSign
| atom # ToAtom
;
atom
: PI # ConstantPI
| E # ConstantE
| DOUBLE # Double
| INT # Int
| ID # Variable
| LPAR plusOrMinus RPAR # Braces
;
有趣的是,当输入一个数字时,比如整数'5',生成的解析树显示运行# Plus和# Multiplication标签。这对我来说没有多大意义。输入中没有+
或*
运算符。我已经上传了下面的解析树的图像,以便更好地了解我正在谈论的内容。
看起来antlr只是默认使用规则中的第一个替代项,但是计算器直接通过标签# Calculate -> # ToMultOrDiv -> # ToPow -> # ToAtom -> # Int
不是更有意义吗?如果没有正确的运算符,它是如何通过# Plus和# Multiplication的呢?
发布于 2018-02-09 21:05:56
观察得很好!我猜ANTLR插件不能正确显示标签。你可以在这里打开一个问题:https://github.com/antlr/intellij-plugin-v4/issues (编辑,我自己打开了一个问题:https://github.com/antlr/antlr4/issues/2222)
当您让输入"5"
通过侦听器时,您将看到显示了正确的路径:
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
public class Main {
static class Listener extends CalculatorBaseListener {
@Override
public void enterCalculate(CalculatorParser.CalculateContext ctx) {
System.out.println("Calculate");
}
@Override
public void enterToMultOrDiv(CalculatorParser.ToMultOrDivContext ctx) {
System.out.println("ToMultOrDiv");
}
@Override
public void enterToPow(CalculatorParser.ToPowContext ctx) {
System.out.println("ToPow");
}
@Override
public void enterPower(CalculatorParser.PowerContext ctx) {
System.out.println("Power");
}
@Override
public void enterToAtom(CalculatorParser.ToAtomContext ctx) {
System.out.println("ToAtom");
}
@Override
public void enterInt(CalculatorParser.IntContext ctx) {
System.out.println("Int");
}
}
public static void main(String[] args) {
CalculatorLexer lexer = new CalculatorLexer(CharStreams.fromString("5"));
CalculatorParser parser = new CalculatorParser(new CommonTokenStream(lexer));
ParseTreeWalker.DEFAULT.walk(new Listener(), parser.input());
}
}
它将打印:
Calculate
ToMultOrDiv
ToPow
Power
ToAtom
Int
https://stackoverflow.com/questions/48713795
复制相似问题