• Antlr4 语法存在错误但语法分析器不报错的问题


    最近使用Antlr4时,遇到了编写的语法存在错误,但生成语法树并不显示错误,只是将报错位置及之后的全部token丢弃的情况。在此对案例进行分享,并分享一下我的解决方案。

    一 问题复现

    下边我用一个简化后的案例复现这个现象

    文法文件如下(ASSIGN.g4):

    grammar ASSIGN;
    
    pfile
        : assignStmt +  //文件由一行或多行赋值语句组成
        ;
    
    assignStmt
        : ID '=' ID operator ID ';'     // 赋值语句是 a = b + c; 格式
        ;
    
    operator
        : '+'|'-'|'*'|'/'
        ;
    
    ID: [a-zA-Z]+ ;
    WS: [ \t\r\n]+ -> skip;
    
    

    下面我们基于此文法生成词法分析器和语法分析器

    > antlr4 ASSIGN.g4
    > javac *.java
    

    下面我们写一个测试文件(test.txt),文件中包含错误的语法

    a = b + c;
    +
    d = e + f;
    

    我们可以看到,第二行的语法是错误的,只有一个加号,不满足assignStmt语法

    下面我们使用这个测试文件生成语法树看下

    > grun ASSIGN pfile -gui test.txt
    

    结果如下,没有显示任何报错,语法树只有第一行的内容!!!
    在这里插入图片描述

    二 排查思路

    语法树没有报错,难道之后的token都被丢了吗?于是我先排查了一下token

    > grun ASSIGN pfile -tokens test.txt
    [@0,0:0='a',<ID>,1:0]
    [@1,2:2='=',<'='>,1:2]
    [@2,4:4='b',<ID>,1:4]
    [@3,6:6='+',<'+'>,1:6]
    [@4,8:8='c',<ID>,1:8]
    [@5,9:9=';',<';'>,1:9]
    [@6,12:12='+',<'+'>,2:0]
    [@7,15:15='d',<ID>,3:0]
    [@8,17:17='=',<'='>,3:2]
    [@9,19:19='e',<ID>,3:4]
    [@10,21:21='+',<'+'>,3:6]
    [@11,23:23='f',<ID>,3:8]
    [@12,24:24=';',<';'>,3:9]
    [@13,25:24='',<EOF>,3:10]
    
    

    由结果我们可以看到,所有的token都被正确的识别了,那只能是语法分析的问题了。之后我再通过trace分析了一下语法分析的过程

    > grun ASSIGN pfile -trace test.txt
    enter   pfile, LT(1)=a
    enter   assignStmt, LT(1)=a
    consume [@0,0:0='a',<7>,1:0] rule assignStmt
    consume [@1,2:2='=',<1>,1:2] rule assignStmt
    consume [@2,4:4='b',<7>,1:4] rule assignStmt
    enter   operator, LT(1)=+
    consume [@3,6:6='+',<3>,1:6] rule operator
    exit    operator, LT(1)=c
    consume [@4,8:8='c',<7>,1:8] rule assignStmt
    consume [@5,9:9=';',<2>,1:9] rule assignStmt
    exit    assignStmt, LT(1)=+
    exit    pfile, LT(1)=+
    
    

    通过trace的最后两行,我们可以看到,在正确识别第一行的assignStmt后遇到了token(+),此时这个token无法让语法分析器匹配任意一个规则,而且此时从最顶层规则pfile退出,语法也是完整的,所以直接从顶层退出,且没有报错。

    三 解决方案

    分析出原因后,解决方案也就有了,我们强制pfile规则匹配到文件结束就可以了,如果不能顺利匹配到文件结束,则说明存在语法错误
    pfile规则进行如下修改

    pfile
        : assignStmt +  EOF//文件由一行或多行赋值语句和文件结束符组成
        ;
    

    重新生成词法分析器和语法分析器,之后重新生成语法树进行验证

    > grun ASSIGN pfile -gui test.txt
    line 2:0 extraneous input '+' expecting {<EOF>, ID}
    
    

    在这里插入图片描述
    此时第二行的语法错误被检测到。

    本文完~

  • 相关阅读:
    北大肖臻老师《区块链技术与应用》系列课程学习笔记[27]以太坊-反思
    Linux(五)__系统管理
    师文汇:OceanBase 4.0 产品核心能力解读
    ssm基于web的酒店预订及个性化服务系统 毕业设计源码241822
    skywalking springgateway 全链路
    Sedex验厂有证书吗?
    字段类型—待补全
    【网站放大镜效果】两种方式实现
    vue双table可拖拽样式(上)
    人体姿态估计(人体关键点检测)2D Pose训练代码和Android源码
  • 原文地址:https://blog.csdn.net/momo3507/article/details/127091655