非常に単純なSQLパーサーを作成しましたが、ファズテスト中にこの状況に遭遇しました。
SELECT 123 + ,
K_SELECT INTEGER T_PLUS T_COMMA
もちろん、これは構文エラーですが、「キャッチ」する方法がわかりません。
「next_column_expressionが早すぎた」と「binary_expressionが終了しなかった」のどちらを判断するのですか。私はJavaプロジェクトでANTLR3とかなり協力してきました。しかし、これはまったく異なります。
スケルトンパーサーのルールは次のとおりです。
/* 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 {
}
;
%%