yacc减少/减少冲突我无法解释

时间:2014-01-07 00:38:26

标签: yacc context-free-grammar

我正在改变/减少并减少/减少我认为不应该发生的冲突。显然我做错了,所以有人向我解释我错过了什么。

我剥离的语法:

/*
 * 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。

1 个答案:

答案 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
            ;

这消除了歧义。