Edit # 1: Ich denke, das Problem ist in meiner .l-Datei. Ich glaube nicht, dass die Regeln als Regeln behandelt werden, und ich bin mir nicht sicher, wie man die Terminals der Regeln als Strings behandeln soll.Flex und Yacc Grammatik Ausgabe
Mein letztes Projekt für eine Compiler-Klasse ist das Schreiben einer .l- und einer .y-Datei für eine einfache SQL-Grammatik. Ich habe keine Erfahrung mit Flex oder Yacc, also habe ich alles, was ich geschrieben habe, zusammengefügt. Ich habe nur ein grundlegendes Verständnis davon, wie diese Dateien funktionieren. Wenn Sie also mein Problem erkennen, können Sie auch erklären, was dieser Teil der Datei tun soll? Ich bin mir nicht einmal sicher, was die '%' Symbole tun.
Grundsätzlich funktionieren einige Regeln einfach nicht, wenn ich versuche, etwas zu analysieren. Einige Regeln hängen und andere lehnen ab, wenn sie akzeptieren sollten. Ich brauche die folgende Grammatik implementieren:
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
Hier meine .l Datei ist:
%{
#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);}
%%
Hier meine .y-Datei ist:
%{
#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() {}
Hier ist mein Make-Datei:
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
Dies funktioniert:
S RENAME CNO AS CITY
Diese nicht:
S
S WHERE CNO = 5
ich alles nicht getestet haben, aber Ich denke, dass es ein gemeinsames Problem für diese Probleme gibt.
Danke, es funktioniert viel besser. Ich habe allerdings ein paar Fragen. Was ist die Überprüfung der if-Anweisung? Ich bin mir nicht sicher, was 'yyin == stdin' bedeutet. Auch jetzt geht das Programm nach einem ab, was wenn ich mehr Befehle eingeben möchte? – Pareod
'yyin == stdin' überprüft, ob die Eingabe von der Standardeingabe kommt, was wir (vielleicht fälschlicherweise) annehmen, dass sie eingegeben wird. In diesem Fall nehmen wir an, dass es das Ende der Eingabe ist. Wenn Sie mehr als eine Zeile akzeptieren möchten, sollten Sie 'yyparse' in eine Schleife einfügen. Alternativ könnten Sie ein ';' nach einem Ausdruck, nur aus Dateien lesen, oder eine Phantasie [repl so] (http://stackoverflow.com/questions/6636808/repl-for-interpreter-using-flex-bison). –