我正在改变/减少并减少/减少我认为不应该发生的冲突。显然我做错了,所以有人向我解释我错过了什么。
我剥离的语法:
/*
* Test SQL Grammar
*/
%{
#include <stdio.h>
#include <string.h>
%}
/* Yacc's YYSTYPE UNION */
%union {
char* str; /* Pointer to constant string (malloc'd in lex) */
}
%token SELECT FROM AS ROWID ROWNUM NEXTVAL CURRVAL NULL
%token <str> IDENTIFIER STRING NUMBER
%%
query_block
: SELECT
select_list
FROM row_source_list
;
select_list
: '*'
| select_item_list
;
select_item_list
: select_item_list ',' select_item
| select_item
;
select_item
: row_source '.' '*'
| expr
| expr IDENTIFIER
;
row_source_list
: row_source_list ',' row_source
| row_source
;
row_source
: IDENTIFIER
| IDENTIFIER '.' IDENTIFIER
| IDENTIFIER opt_AS IDENTIFIER
| IDENTIFIER '.' IDENTIFIER opt_AS IDENTIFIER
;
opt_AS
: /* Empty */
| AS
;
expr
: IDENTIFIER '.' IDENTIFIER
| IDENTIFIER '.' ROWID
| IDENTIFIER '.' IDENTIFIER '.' IDENTIFIER
| IDENTIFIER '.' IDENTIFIER '.' ROWID
| ROWNUM
| ROWID
| STRING
| NUMBER
| IDENTIFIER '.' CURRVAL
| IDENTIFIER '.' NEXTVAL
| NULL
;
冲突似乎出现了,因为yacc不知道它是否正在处理select_list(expr列表)或row_source_list。 y.output的状态26详述了冲突:
state 26
12 row_source: IDENTIFIER '.' IDENTIFIER .
14 | IDENTIFIER '.' IDENTIFIER . opt_AS IDENTIFIER
17 expr: IDENTIFIER '.' IDENTIFIER .
19 | IDENTIFIER '.' IDENTIFIER . '.' IDENTIFIER
20 | IDENTIFIER '.' IDENTIFIER . '.' ROWID
AS shift, and go to state 16
'.' shift, and go to state 33
IDENTIFIER reduce using rule 15 (opt_AS)
IDENTIFIER [reduce using rule 17 (expr)]
'.' [reduce using rule 12 (row_source)]
$default reduce using rule 17 (expr)
opt_AS go to state 34
现在“query_block”的基本规则指出row_source_list必须以“FROM”关键字开头,所以我不明白为什么yacc将两者合并为一个状态。
query_block
: SELECT
select_list
FROM row_source_list
;
我已跟踪状态,并在找到“FROM”关键字之前最终处于此状态。 我不明白为什么在认可“FROM”之前考虑row_source_list。
答案 0 :(得分:0)
(我将此标记为“不再可再现的错误”,因为OP已经解决了这个问题,但是标志已经老化/超时了。)
As it has an answer I'll transcribe the answer so at least the question is noted as answered.
OP表示:
发布后我发现它。这是select_item规则中的第一行。我应该早点抓住它。
要澄清的是,select_item
规则应为:
select_item
: expr
| expr IDENTIFIER
;
这消除了歧义。