2014-01-07 97 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。

回答