2014-01-07 72 views
2

我得到了一个转变/减少和减少/减少冲突,我认为不应该发生。很明显,我做错了什么,所以有人向我解释我错过了什么。yacc减少/减少冲突我无法解释

我剥了下来语法:

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

的冲突似乎arrise因为YACC不知道它是否工作在select_list中(表达式列表)或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。

回答