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