2012-04-25 63 views
0

我是新來的LEX/YACC,我使用的lex/yacc.However特定連接查詢(如下所示)我解析器是故意訪問「select_statement中」的規則寫SQL解析器而不是'nested_join_statement'規則。面臨的lex/yacc的程序錯誤奇

我正在此查詢正確的輸出:SELECT * FROM SAMPLE1 JOIN SAMPLE2 ON sample1.C1 = sample2.C4;
(這要到 'join_statement規則',滿足內simple_join規則)

但是當我嘗試此查詢:SELECT * FROM(SELECT * FROM(SELECT * FROM SAMPLE1)T8)AS temp1中JOIN(SELECT * FROM(SELECT * FROM sample2)T9)as temp2 ON temp1.C1 = temp2.​​C4; (理想情況下,這應該轉到'nested_join_statement',但是它將轉到'SELECT語句'規則中的SELECT選擇FROM LPAREN select_statement2 RPAREN VAR'規則,並且我收到以下錯誤消息:錯誤:語法錯誤,意想不到的AS,期待VAR)

我在select_statement中優先配售的nested_join_statement但仍獲得此錯誤。我不明白爲什麼。

在該法VAR被定義爲[A-ZA-Z] [A-ZA-Z0-9 _# - ] *

任何幫助,將不勝感激。我很絕望。

manipulation_statement: NEWLINE 
      | join_statement SEMICOLON 
      | nested_join_statement SEMICOLON 
      | select_statement SEMICOLON { flag=0;q=0;} 
      | join_statement SEMICOLON NEWLINE 
      | nested_join_statement SEMICOLON NEWLINE 
      | select_statement SEMICOLON NEWLINE { flag=0;q=0;} 
      ; 
    nested_join_statement: two_nest_select_join { for(x=0;x<q;x++) strcpy(sj[x], ""); i=0;j=0;vardot=0;q=0;flag=0;nest=0;} 
      ; 
    join_statement: 
      simple_join { for(x=0;x<q;x++) strcpy(sj[x], ""); i=0;j=0;vardot=0;q=0;flag=0;} 
      | simple_join_nest_select { for(x=0;x<q;x++) strcpy(sj[x], ""); i=0;j=0;vardot=0;q=0;flag=0;} 
      ; 
    simple_join: SELECT selection FROM VAR JOIN VAR ON VAR DOTS VAR EQUAL VAR DOTS VAR { printf("inside simple join\n");                 
                  if(strcmp($4,$8) == 0) join_table($4,$6,sj,q,$10,$14,"",""); 
                  else join_table($4,$6,sj,q,$14,$10,"",""); p=q;} 
     ; 

    simple_join_nest_select: SELECT selection FROM VAR JOIN LPAREN select_statement RPAREN AS VAR ON VAR DOTS VAR EQUAL VAR DOTS VAR { 
                if (strcmp($4,$12) == 0) join_table($4,"_temp_",sj,q,$14,$18,"",""); 
                else join_table($4,"_temp_",sj,q,$18,$14,"",""); p=q;} 
     ; 

    two_nest_select_join: SELECT selection FROM LPAREN select_statement RPAREN AS VAR JOIN LPAREN select_statement RPAREN AS VAR ON VAR DOTS VAR EQUAL VAR DOTS VAR { 
             join_table("temp1","temp2",sj,q,$18,$22,"",""); } 
     ; 

    select_statement: SELECT selection FROM VAR WHERE where_clause { select_table($4,s,i,whr_var,whr_val); 
                  for(x=0;x<i;x++) strcpy(s[x],"");i=0; strcpy(whr_var,""); strcpy(whr_val,"");j=0;} 
      | SELECT selection FROM VAR { select_table($4,s,i,whr_var,whr_val); 
              for(x=0;x<i;x++) strcpy(s[x],"");i=0;j=0;} 
      | SELECT selection FROM LPAREN select_statement2 RPAREN VAR { printf("inner tab: %s\n", inner_tab); printf("dep:%d\n", dep+1); 
                      for(x=0; x<i;x++) printf("%s\n", col_array[x]); 
                      for(y=0; y<j;y++) printf("%d\n", col_count[y]); 
                      strcpy(inner_tab,""); nest =1; dep=0; 
                      for(x=0; x<i;x++) strcpy(col_array[x], ""); 
                      for(y=0; y<j;y++) col_count[x] =0; 
                      i=0;j=0;k=0;m=0;} 
      ; 
    select_statement2: SELECT selection2 FROM VAR { dep++; inner_tab=malloc(strlen($4)); strcpy(inner_tab,$4); } 
       | select_list 
      ; 
    select_list: SELECT selection2 FROM LPAREN select_statement2 RPAREN VAR { dep++; } 
     ; 
    selection2: ASTERISK { col_array[i] = $1; i++; m++; col_count[j] = m; j++; printf("in level:%d value of k:%d\n",j,m); k=0; m=0;} 
     | comma_list2 { col_count[j] = m; j++; printf("in level:%d value of k:%d\n",j,m); k=0; m=0; } 
     ; 
    comma_list2: VAR { col_array[i] = $1; i++; m++;} 
     | comma_list2 COMMA VAR { col_array[i] = $3; i++; m++; 
            k=m;} 
     ; 
    selection: ASTERISK { if(q != 0 || nest == 1) { for(x=0;x<j;x++) col_count[x]=0; i=0; j=0;flag=1;} 
         s[i] = $1; col_array[i] = $1; i++; col_count[j] = i; j++; 
         if(q == 0) {sj[q] = $1; q++;} printf("in level t:%d value of k:%d\n",j,i); printf("sj2:%s\n",sj[0]);} 
     | comma_list { if (flag ==1) {col_count[j] = i; j++; printf("in level 2:%d value of k:%d\n",j,i); k=0; m=0; printf("temp:"); 
            for(x=0;x<i;x++) printf("%s ",s[x]); } else {col_count[j] = i; j++;} } 
     ; 
    comma_list: 
     VAR { if(q != 0 || nest == 1) { for(x=0;x<j;x++) col_count[x]=0; i=0; j=0;flag=1;} 
       s[i] = $1; col_array[i] = $1; i++; if(q==0) {sj[q] = $1; q++; }} 
     | VAR DOTS VAR { strcpy(temp,""); strcat(temp,$1); strcat(temp,$2); strcat(temp,$3); 
      sj[q] = temp; q++; 
      printf("temps:"); for(x=0;x<q;x++) printf("%s\n",sj[x]);} 
     | comma_list COMMA vardot {if (flag == 1) { s[i] = $3; col_array[i] = $3, i++;} else {sj[q] = $3; q++; vardot++;s[i] = $3; col_array[i] = $3, i++;} 
                      } 
     ; 
+0

我用gnu-Flex取代了Adobe Flex標籤;因爲我認爲這對你的問題更合適。 – JeffryHouser 2012-04-25 16:50:56

+1

是的,你們會繼續爲新的GNU Flex問題做這件事,直到您爲Adobe Flex標籤選擇更合理的拼寫爲止! – Kaz 2012-04-25 18:34:06

回答

2

你減少/降低你的語法衝突 - 選擇和選擇2之間,並且comma_list和comma_list2之間。由於「2」版本是第一位在你的語法文件,它總是會減少使用這些規則,這意味着在任何地方,它不能告訴select_statement中和select_statement2之間的區別僅僅通過看一切達相關的'FROM'令牌可能會做錯誤的事情。

在您的例子,它看到SELECT * FROM (SELECT * FROM後,它必須做出這樣的選擇(因爲在括號嵌套查詢可能是A選擇的two_nest_select_join,或者一個簡單的select_statement中一個選擇2),並選擇選擇2,所以分析這是一個select_statement中,導致你看時,得到的AS令牌錯誤 - 它期待VAR

如果要解決這個問題,你需要或者使用更前瞻,或改變語法擺脫減少/減少衝突。

要使用更前瞻,您可以使用野牛的%glr-parser選項。既然你沒有歧義這裏,你不需要添加任何額外的消歧代碼,但如果你有歧義的其他地方,你可能會得到運行時錯誤的結果。

爲了擺脫減少/減少衝突,您需要擺脫重複的選擇2規則 - 如果您將它們全部更改爲相應的選擇規則,則可以消除衝突,但是現在您可以接受一些(例如SELECT * FROM (SELECT * FROM VAR WHERE where_clause) VAR,你可能不想這麼做)