簡體   English   中英

Flex和Yacc語法問題

[英]Flex and Yacc Grammar Issue

編輯#1:我認為問題出在我的.l文件中。 我不認為規則被視為規則,並且我不確定如何將規則的終端視為字符串。

對於編譯器類,我的最后一個項目是為簡單的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

這有效:

重命名CNO為城市

這些不:

小號

S CNO = 5

我尚未測試所有內容,但我認為這些問題存在一個普遍的問題。

您的語法是正確的,問題是您正在交互式運行。 當您調用yyparse()時,它將嘗試讀取所有輸入。 因為輸入

小號

后面可能跟有RENAME或WHERE,它將不被接受。 同樣,

S CNO = 5

可能后跟一個或多個數字,因此yyparse不會接受,直到獲得EOF或意外的令牌。

您要做的是按照此處的建議進行操作並將p5.l更改為以下行:

[ \t]+        ;
\n            if (yyin==stdin) return 0;

這樣,當您以交互方式運行時,它將以ENTER鍵作為輸入的結尾。

另外,您想對數字使用左遞歸

number:
    val
    | number val
    ;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM