C 作为上述*expr:value状态的一部分结束,因此错误恢复将停止在那里弹出,并移动错误标记,最终处于可以移动,标记的状态

C 作为上述*expr:value状态的一部分结束,因此错误恢复将停止在那里弹出,并移动错误标记,最终处于可以移动,标记的状态,c,bison,flex-lexer,C,Bison,Flex Lexer,每当您试图解开大型语法中的状态并了解错误恢复将做什么时,使用-v标志运行yacc/bison以生成一个包含所有状态的.output文件将非常有帮助。选择一个或另一个,然后继续。关于Yacc错误处理的更多信息,为什么不阅读Google上的第一篇文章:我宁愿它决定二进制_表达式的格式不正确,并跳转到一些退出代码中。所以,“,”只会在处达到峰值,它不会尝试读取下一列的\u表达式?Yacc有一个特殊的“错误”生成,您可以在策略点(例如分号之前)插入它,以便在下一条语句中恢复解析。查看文档了解详细信息。是

每当您试图解开大型语法中的状态并了解错误恢复将做什么时,使用-v标志运行yacc/bison以生成一个包含所有状态的
.output
文件将非常有帮助。

选择一个或另一个,然后继续。关于Yacc错误处理的更多信息,为什么不阅读Google上的第一篇文章:我宁愿它决定二进制_表达式的格式不正确,并跳转到一些退出代码中。所以,“,”只会在处达到峰值,它不会尝试读取下一列的\u表达式?Yacc有一个特殊的“错误”生成,您可以在策略点(例如分号之前)插入它,以便在下一条语句中恢复解析。查看文档了解详细信息。是的,我知道“错误”,你可以看到我已经在使用它来处理一些情况。我的问题是,我需要使用什么语法来从过早的二进制表达式中恢复?我认为bison只在前面读到一个标记,所以我认为它应该如何工作并不需要点击其中一个,然后继续。关于Yacc错误处理的更多信息,为什么不阅读Google上的第一篇文章:我宁愿它决定二进制_表达式的格式不正确,并跳转到一些退出代码中。所以,“,”只会在处达到峰值,它不会尝试读取下一列的\u表达式?Yacc有一个特殊的“错误”生成,您可以在策略点(例如分号之前)插入它,以便在下一条语句中恢复解析。查看文档了解详细信息。是的,我知道“错误”,你可以看到我已经在使用它来处理一些情况。我的问题是,我需要使用什么语法来从过早的二进制表达式中恢复?我想bison只会在前面读到一个标记,所以我认为它应该如何工作并不感谢你,这真的很有帮助。我有点理解你的意思,但我还需要进一步研究。我设法解决了我的问题,将二进制表达式简化为几个子规则,在我需要的地方有错误条件,所以“二进制表达式:值二进制表达式\u op二进制表达式\u right”没有泄漏,没有崩溃,它正在做它应该做的一切:)谢谢,这真的很有帮助。我有点理解你的意思,但我还需要进一步研究。我设法解决了我的问题,将二进制表达式简化为几个子规则,在我需要的地方有错误条件,所以“二进制表达式:值二进制表达式\u op二进制表达式\u right”没有泄漏,没有崩溃,它正在做它应该做的一切:)
SELECT   123     +      ,
K_SELECT INTEGER T_PLUS T_COMMA
/* be more versbose about error messages */
%error-verbose

/* keywords */
%token K_CREATE
%token K_FROM
%token K_INTEGER
%token K_SELECT
%token K_TABLE
%token K_TEXT
%token K_WHERE
%token K_VALUES
%token K_INSERT
%token K_INTO

/* variable tokens */
%token IDENTIFIER
%token INTEGER

/* fixed tokens */
%token T_ASTERISK
%token T_PLUS
%token T_EQUALS
%token T_END ";"
%token T_COMMA
%token T_BRACKET_OPEN
%token T_BRACKET_CLOSE

%token END 0 "end of file"

%%

input:
    statement {
    }
    END
;

statement:
    select_statement {
    }
    |
    create_table_statement {
    }
    |
    insert_statement {
    }
;

keyword:
    K_CREATE | K_FROM | K_INTEGER | K_SELECT | K_TABLE | K_TEXT | K_WHERE | K_VALUES | K_INSERT | K_INTO
;

table_name:
    error {
        // "Expected table name"
    }
    |
    keyword {
        // "You cannot use a keyword for a table name."
    }
    |
    IDENTIFIER {
    }
;

select_statement:
    K_SELECT column_expression_list {
        // "Expected FROM after column list."
    }
    error
    |
    K_SELECT error {
        // "Expected column list after SELECT."
    }
    |
    K_SELECT column_expression_list {
    }
    K_FROM table_name {
    }
;

column_expression_list:
    column_expression {
    }
    next_column_expression
;

column_expression:
    T_ASTERISK {
    }
    |
    expression {
    }
;

next_column_expression:
    |
    T_COMMA column_expression {
    }
    next_column_expression
;

binary_expression:
    value {
    }
    operator {
    }
    value {
    }
;

expression:
    value
    |
    binary_expression
;

operator:
    T_PLUS {
    }
    |
    T_EQUALS {
    }
;

value:
    INTEGER {
    }
    |
    IDENTIFIER {
    }
;

%%
binary_expression: value error