Bison 野牛与图案匹配的顺序是什么? 描述

Bison 野牛与图案匹配的顺序是什么? 描述,bison,Bison,我想用bison实现json文件的语法检测器 我曾经 识别语法错误,如[“额外逗号”,],但失败。但是对象的类似模式也适用。我认为这可能与图案顺序有关 然而,当我使用 Values: Value | Value COMMA Values | Value COMMA error { puts("extra comma, recovered"); } 它成功了。我想知道为什么 Value COMMA error { puts(&qu

我想用bison实现json文件的语法检测器

  • 我曾经 识别语法错误,如
    [“额外逗号”,]
    ,但失败。但是
    对象
    的类似模式也适用。我认为这可能与图案顺序有关
  • 然而,当我使用
    Values: Value
          | Value COMMA Values
          | Value COMMA error
               { puts("extra comma, recovered"); }
    
    它成功了。我想知道为什么
    Value COMMA error { puts("extra comma, recovered"); }
    
    不会与应为
    值逗号值的文本不匹配
  • 源代码 syntax.y

    %{
        #include"lex.yy.c"
        void yyerror(const char*);
    %}
    
    %token LC RC LB RB COLON COMMA
    %token STRING NUMBER
    %token TRUE FALSE VNULL
    %%
    
    Json:
          Value
        ;
    Value:
          Object
        | Array
        | STRING
        | NUMBER
        | TRUE
        | FALSE
        | VNULL
        ;
    Object:
          LC RC
        | LC Members RC
        | LC Member COMMA RC error { puts("extra comma, recovered"); }
        ;
    Members:
          Member
        | Member COMMA Members
        ;
    Member:
          STRING COLON Value
        ;
    Array:
          LB RB
        | LB Values RB
        | LB Values RC error { puts("unmatched right bracket, recovered"); }
        ;
    Values:
          Value
        | Value COMMA Values
        | Value COMMA error { puts("extra comma, recovered"); }
        ;
    %%
    
    void yyerror(const char *s){
        printf("syntax error: ");
    }
    
    int main(int argc, char **argv){
        if(argc != 2) {
            fprintf(stderr, "Usage: %s <file_path>\n", argv[0]);
            exit(-1);
        }
        else if(!(yyin = fopen(argv[1], "r"))) {
            perror(argv[1]);
            exit(-1);
        }
        yyparse();
        return 0;
    }
    

    当bison解析器无法使用lookahead令牌时,
    错误
    令牌由bison解析器自动生成。如果当前解析器状态有这样的移位操作,那么它可以通过移位
    错误
    标记来取得进展

    除非生成了
    错误
    标记,否则不能使用包含
    错误
    标记的产品

    在移动
    错误
    标记后,解析器将尝试匹配包含它的产品的其余部分。如有必要,它将跳过输入,直到找到可以移位的令牌。可用于同步解析的。因此,看到这样的模式是很常见的

    Array: '[' Values ']'
         | '[' Values error ']'
    
    它试图匹配结束括号

    或者,您可以以类似于第二个示例的方式重新启动解析。(这里我使用左递归,如果列表很长,这通常是一个更好的选择,因为左递归不需要使用解析堆栈):

    如果要在输入包含尾随逗号的情况下产生特定错误,最好的方法是只包含一条普通规则:

    Array: '(' Values ',' ')' { /* Signal the error */ }
    
    良好的错误识别是一门艺术,而不是一门科学。一定量的实验几乎总是必要的



    在大多数应用程序中,最好是立即拒绝无效的JSON,而不是试图生成有意义的错误消息,更不用说继续解析了。JSON通常是机器生成的,应该是正确的;如果不是,则没有用于发送有意义错误的反向通道,也没有人可以发送错误。格式不正确的交换字符串通常会引发漏洞,因此应予以处理。(当然,你的申请可能是个例外。但经验表明,立即拒绝几乎总是最好的策略,也是最简单的。)

    谢谢你的回答。但我仍然不明白为什么`数组:…|LB值逗号RB错误`不起作用?
    Array: '[' Values ']'
         | '[' Values error ']'
    
    Values: Value
          | Values ',' Value
          | Values error
    
    Array: '(' Values ',' ')' { /* Signal the error */ }