編輯#1:我認爲問題出在我的.l文件中。我不認爲規則被視爲規則,我不知道如何將規則的終端視爲字符串。Flex和Yacc語法問題
我編譯器類的最後一個項目是爲一個簡單的SQL語法編寫一個.l和一個.y文件。我沒有Flex或Yacc的經驗,所以我寫的所有東西都拼湊在一起。我只對這些文件的工作原理有一個基本的瞭解,所以如果你發現我的問題,你是否也可以解釋文件的那部分應該做什麼?我甚至不確定'%'符號的作用。
基本上,當我嘗試解析某些內容時,某些規則不起作用。有些規則是懸而未決的,而有些則是在他們接受時拒絕。我需要實現以下語法:
start
::= expression
expression
::= one-relation-expression | two-relation-expression
one-relation-expression
::= renaming | restriction | projection
renaming
::= term RENAME attribute AS attribute
term
::= relation | (expression)
restriction
::= term WHERE comparison
projection
::= term | term [ attribute-commalist ]
attribute-commalist
::= attribute | attribute , attribute-commalist
two-relation-expression
::= projection binary-operation expression
binary-operation
::= UNION | INTERSECT | MINUS | TIMES | JOIN | DIVIDEBY
comparison
::= attribute compare number
compare
::= < | > | <= | >= | = | <>
number
::= val | val number
val
::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
attribute
::= CNO | CITY | CNAME | SNO | PNO | TQTY |
SNAME | QUOTA | PNAME | COST | AVQTY |
S# | STATUS | P# | COLOR | WEIGHT | QTY
relation
::= S | P | SP | PRDCT | CUST | ORDERS
這裏是我的.L文件:
%{
#include <stdio.h>
#include "p5.tab.h"
%}
binaryOperation UINION|INTERSECT|MINUS|TIMES|JOIN|DIVIDEBY
compare <|>|<=|>=|=|<>
attribute CNO|CITY|CNAME|SNO|PNO|TQTY|SNAME|QUOTA|PNAME|COST|AVQTY|S#|STATUS|P#|COLOR|WEIGHT|QTY
relation S|P|SP|PRDCT|CUST|ORDERS
%%
[ \t\n]+ ;
{binaryOperation} return binaryOperation;
{compare} return compare;
[0-9]+ return val;
{attribute} return attribute;
{relation} return relation;
"RENAME" return RENAME;
"AS" return AS;
"WHERE" return WHERE;
"(" return '(';
")" return ')';
"[" return '[';
"]" return ']';
"," return ',';
. {printf("REJECT\n");
exit(0);}
%%
這裏是我的.Y文件:
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token RENAME attribute AS relation WHERE binaryOperation compare val
%%
start:
expression {printf("ACCEPT\n");}
;
expression:
oneRelationExpression
| twoRelationExpression
;
oneRelationExpression:
renaming
| restriction
| projection
;
renaming:
term RENAME attribute AS attribute
;
term:
relation
| '(' expression ')'
;
restriction:
term WHERE comparison
;
projection:
term
| term '[' attributeCommalist ']'
;
attributeCommalist:
attribute
| attribute ',' attributeCommalist
;
twoRelationExpression:
projection binaryOperation expression
;
comparison:
attribute compare number
;
number:
val
| val number
;
%%
yyerror() {
printf("REJECT\n");
exit(0);
}
main() {
yyparse();
}
yywrap() {}
這裏是我的makefile:
p5: p5.tab.c lex.yy.c
cc -o p5 p5.tab.c lex.yy.c
p5.tab.c: p5.y
bison -d p5.y
lex.yy.c: p5.l
flex p5.l
此作品:
小號RENAME CNO作爲市
這些不:
小號
S其中CNO = 5
我沒有測試過的一切,但我認爲這些問題存在一個共同的問題。
謝謝,它的工作要好得多。但我有幾個問題。 if語句是什麼檢查?我不確定'yyin == stdin'的含義。另外,現在程序在一次接受後退出,如果我想輸入更多命令,該怎麼辦? – Pareod
'yyin == stdin'檢查輸入是否來自標準輸入,我們(可能錯誤地)假設輸入是輸入的。在這種情況下,當用戶輸入時,我們假設它是輸入的結尾。如果你想接受多行,你應該把'yyparse'放在一個循環中。或者,您可能需要';'在一個表達式之後,只能從文件中讀取,或者做一個花哨的[repl像這樣](http://stackoverflow.com/questions/6636808/repl-for-interpreter-using-flex-bison)。 –