【问题标题】:ANTLR4 book, calculator exerciseANTLR4 书,计算器练习
【发布时间】:2014-03-13 17:45:36
【问题描述】:

我在 antlr 的基础上陷入了困境。阅读 Parr 博士的“权威 ANTLR 4 参考”。在第 4.2 节“使用访问者构建计算器”中列出了以下语法:

grammar LabeledExpr; // rename to distinguish from Expr.g4

prog:   stat+ ;

stat:   expr NEWLINE                # printExpr
    |   ID '=' expr NEWLINE         # assign
    |   NEWLINE                     # blank
    ;

expr:   expr op=('*'|'/') expr      # MulDiv
    |   expr op=('+'|'-') expr      # AddSub
    |   INT                         # int
    |   ID                          # id
    |   '(' expr ')'                # parens
    ;

MUL :   '*' ; // assigns token name to '*' used above in grammar
DIV :   '/' ;
ADD :   '+' ;
SUB :   '-' ;
ID  :   [a-zA-Z]+ ;      // match identifiers
INT :   [0-9]+ ;         // match integers
NEWLINE:'\r'? '\n' ;     // return newlines to parser (is end-statement signal)
WS  :   [ \t]+ -> skip ; // toss out whitespace

我正在尝试在上面添加clear 声明,来自书中:

在继续之前,您可能会花点时间尝试通过添加clear 语句来扩展这种表达式语言。 clear 命令应该清除 memory 映射,并且您需要规则 stat 中的新替代项来识别它。用# clear 标记替代方案,然后在语法上运行ANTLR 以获得增强的访问者界面。

这是我的尝试:

grammar LabeledExpr;

prog:   stat+ ;

stat:   expr NEWLINE          # printExpr
    |   ID '=' expr NEWLINE   # assign
    |   clear NEWLINE         # clearMem
    |   NEWLINE               # blank
    ;

expr:   expr op=('*'|'/') expr   # MulDiv
    |   expr op=('+'|'-') expr   # AddSub
    |   INT                   # int
    |   ID                    # id
    |   '(' expr ')'          # parens
    ;

clear:  CLEAR               
    ;

MUL:    '*' ;   // assigns token name to '*' used above in grammar
DIV:    '/' ;
ADD:    '+' ;
SUB:    '-' ;

ID  :   [a-zA-Z]+ ;
INT :   [0-9]+ ;
NEWLINE: '\r'?'\n' ;
WS  :   [ \t]+ -> skip ;
CLEAR:  'clear';

但是,visitClearMem 永远不会被调用:

@Override
public Integer visitClearMem(LabeledExprParser.ClearMemContext ctx) {
    String text = ctx.getText();
    if (text.equalsIgnoreCase("clear")) {
        memory.clear();
    }
    return 0;
}

【问题讨论】:

  • 我知道这已经超过 3 年了,但你能发布一下你是如何修复它的吗?

标签: antlr antlr4


【解决方案1】:

问题在于您的词法分析器中CLEAR 规则的位置。由于输入clear 匹配规则IDCLEAR,ANTLR 选择出现在语法中的第一个。在这种情况下,输入 clear 变为 ID

通常,您希望将您语言的所有关键字放在其他标识符的规则之前,以确保它们正确匹配。

【讨论】:

    【解决方案2】:

    正如 Sam Harwell 所解释的,只需将规则向上移动 CLEAR: 'clear';在 ID 规则之前,它可以工作并且对代码进行小幅修改

    @Override
    public Integer visitClearMem(LabeledExprParser.ClearMemContext ctx) {
        String text = ctx.getText();
        if (text.contains("clear")) {
            memory.clear();
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多