0
我想使用lex/yacc編寫我自己的編譯器,只有兩個代碼,我指示它像這樣運行(現在沒有額外的頭文件)。窗口上lex/yacc的問題
所以這是我的lex文件(FP.L):
%{
#include "FP.tab.h"
%}
KEYWORD Program|Function|return|if|then|else|while|do|or|and|print
PROG "Program"
FUNC "Function"
RET "return"
PRINT "print"
IF "if"
THEN "then"
ELSE "else"
WHILE "while"
DO "do"
OR "or"
AND "and"
F "}"
SPECIAL ">="|"<="|"!="|"=="
O "{"
PREFUNC ["+"|\-|"*"|"/"|"%"]
SYMBOL [">"|"<"]
ASS "="
FLOAT [-]?[ \t\n]*[0-9]+"."[0-9]+
INT [-]?[ \t\n]*[1-9][0-9]*|[0]
STRING [(][a-zA-Z0-9 \n\t]+[)]
BOOL T|F
ID [a-zA-Z][a-zA-Z0-9]{0,5}
%%
[ \t\n\r]+ //do nothing
{SYMBOL} { sscanf(yytext, "%s", yylval.chari); return(SYMBOL); }
{PROG} { sscanf(yytext, "%s", yylval.chari); return(PROG); }
{FUNC} { sscanf(yytext, "%s", yylval.chari); return(FUNC); }
{RET} { sscanf(yytext, "%s", yylval.chari); return(RET); }
{PRINT} { sscanf(yytext, "%s", yylval.chari); return(PRINT); }
{IF} { sscanf(yytext, "%s", yylval.chari); return(IF); }
{THEN} { sscanf(yytext, "%s", yylval.chari); return(THEN); }
{ELSE} { sscanf(yytext, "%s", yylval.chari); return(ELSE); }
{WHILE} { sscanf(yytext, "%s", yylval.chari); return(WHILE); }
{DO} { sscanf(yytext, "%s", yylval.chari); return(DO); }
{OR} { sscanf(yytext, "%s", yylval.chari); return(OR); }
{AND} { sscanf(yytext, "%s", yylval.chari); return(AND); }
{O} { sscanf(yytext, "%s", yylval.chari); return(O); }
{F} { sscanf(yytext, "%s", yylval.chari); return(F); }
{PREFUNC} { sscanf(yytext, "%s", yylval.chari); return(PREFUNC); }
{SPECIAL} { sscanf(yytext, "%s", yylval.chari); return (SPECIAL); }
{FLOAT} { sscanf(yytext, "%f", &yylval.floati); return (FLOAT);}
{INT} { sscanf(yytext, "%d", &yylval.inti); return (INT);}
{BOOL} { sscanf(yytext, "%s", yylval.chari); return (BOOL);}
{ASS} { sscanf(yytext, "%s", yylval.chari); return(ASS);}
{STRING} { sscanf(yytext, "%s", yylval.chari); return (STRING);}
{ID} { sscanf(yytext, "%s", yylval.chari); return (ID);}
%%
int yywrap() { return 1; }
,這是我的yacc文件(FP.y):
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _XOPEN_SOURCE
#define MAXSIZE 1000
int i = 0;
unsigned long scope_number = 0;
typedef struct un_stack{
unsigned long info;
char string[128];
struct un_stack *next;
}stack;
stack *stk = NULL;
typedef struct un_hash{
stack* index[7];
}hash;
hash initialize_hash(hash h)
{
int j;
for(j=0;j<7;j++)
h.index[j]=NULL;
return h;
}
hash h;
stack *push(stack *l, unsigned long n)
{
stack *new = (stack*)malloc(sizeof(stack));
new->info = n;
new->next = l;
return new;
}
stack *insert(stack *l, unsigned long n, char *str)//for a chained list...
{
stack *new = (stack*)malloc(sizeof(stack));
new->info = n;
strcpy(new->string,str);
new->next = l;
return new;
}
stack *pop(stack *l)
{
stack *aux = l->next;
free(l);
return aux;
}
unsigned long top(stack *l)//return scope_number
{
return l->info;
}
int func_hash(char *str)
{
int count =0;
while(1){
if(*(str + count) == '\0') break;
count++;
}
int i=0;
int total = 0;
for(;i<count;i++){
total+= str[i] - '\0';
}
return total%7;
}
hash process_line(char* identifier, hash h)
{
int j;
if(strcmp(identifier, "{") == 0)
{
scope_number++;
stk = push(stk, scope_number);
}
else if(strcmp(identifier, "}") == 0)
stk = pop(stk);
else
h.index[func_hash(identifier)] = insert(h.index[func_hash(identifier)], top(stk), identifier);
return h;
}
void display(stack *l)
{
for(;l!=NULL;l=l->next){
printf("[Scope= %lu Token= %s ]", l->info, l->string);
printf("->");
}
}
typedef struct arvgen{
char info[120];
struct arvgen *st;
struct arvgen *next;
}arvgen;
arvgen* gcria(char *c)
{
arvgen *a =(arvgen *) malloc(sizeof(arvgen));
strcpy(a->info,c);
a->st = NULL;
a->next = NULL;
return a;
}
arvgen* gcria2(arvgen *c)
{
arvgen *a =(arvgen *) malloc(sizeof(arvgen));
strcpy(a->info," ");
a->st = NULL;
a->next = NULL;
return a;
}
void ginsere(arvgen* a, arvgen* sa)
{
sa->next = a->st;
a->st = sa;
}
void gimprime(arvgen* a)
{
arvgen* p;
printf("<%s",a->info);
for (p=a->st; p!=NULL; p=p->next)
gimprime(p);
printf(">");
}
void pint(){ printf("teste");}
%}
%union{
int inti;
float floati;
char chari[120];
arvgen *nexti;
}
%start program
%token <inti> INT
%token <floati> FLOAT
%token <chari> STRING PROG FUNC RET PRINT IF THEN ELSE WHILE DO OR AND O F PREFUNC SYMBOL ASS SPECIAL BOOL ID
%type <nexti> definitions def args arg retarg stms stmt ass funccall prefunc parameters parameter number if while exp compoperation booloperation program
%%
program : O PROG ID definitions stms F { h = process_line($3, h);
arvgen* root = gcria("program");
arvgen* o = gcria($1);
arvgen* prog = gcria($2);
arvgen* id = gcria($3);
arvgen* def = $4;
arvgen* stt = $5;
arvgen* f = gcria($6);
ginsere(root,f);
ginsere(root,stt);
ginsere(root,def);
ginsere(root,id);
ginsere(root,prog);
ginsere(root,o);
gimprime(root);
$$ = root;
}
;
definitions : { $$ = gcria2(NULL); }
| definitions def { arvgen* pai = gcria("definitions");
arvgen* fi1 = $1;
arvgen* fi2 = $2;
ginsere(pai,fi2);
ginsere(pai,fi1);
$$ = pai;
}
;
def : O FUNC ID args stms RET retarg F { h = process_line($3, h);
arvgen* pai2 = gcria("def");
arvgen* o2 = gcria($1);
arvgen* func2 = gcria($2);
arvgen* id2 = gcria($3);
arvgen* args2 = $4;
arvgen* stms2 = $5;
arvgen* ret2 = gcria($6);
arvgen* reta2 = $7;
arvgen* f2 = gcria($8);
ginsere(pai2,f2);
ginsere(pai2,reta2);
ginsere(pai2,ret2);
ginsere(pai2,stms2);
ginsere(pai2,args2);
ginsere(pai2,id2);
ginsere(pai2,func2);
ginsere(pai2,o2);
$$ = pai2;
}
;
args : { $$ = gcria2(NULL); }
| args arg {
arvgen* pai3 = gcria("args");
arvgen* args3 = $1;
arvgen* arg3 = $2;
ginsere(pai3,arg3);
ginsere(pai3,args3);
$$ = pai3;
}
;
arg : ID { h = process_line($1, h);
arvgen* pai4 = gcria("arg");
arvgen* id4 = gcria($1);
ginsere(pai4,id4);
$$ = pai4;
}
;
retarg : { $$ = gcria2(NULL); }
|ID { h = process_line($1, h);
arvgen* pai5 = gcria("retarg");
arvgen* id5 = gcria($1);
ginsere(pai5,id5);
$$ = pai5;
}
;
stms : stmt {
arvgen* pai6 = gcria("stms");
arvgen* id6 = $1;
ginsere(pai6,id6);
$$ = pai6;
}
| stms stmt {
arvgen* pai7 = gcria("stms");
arvgen* stms7 = $1;
arvgen* stmt7 = $2;
ginsere(pai7,stmt7);
ginsere(pai7,stms7);
$$ = pai7;
}
;
stmt : ass {
arvgen* pai8 = gcria("stmt");
arvgen* ass8 = $1;
ginsere(pai8,ass8);
$$ = pai8;
}
| funccall {
arvgen* pai9 = gcria("stmt");
arvgen* funcal9 = $1;
ginsere(pai9,funcal9);
$$ = pai9;
}
| if {
arvgen* pai10 = gcria("stmt");
arvgen* if10 = $1;
ginsere(pai10,if10);
$$ = pai10;
}
| while {
arvgen* pai11 = gcria("stmt");
arvgen* while11 = $1;
ginsere(pai11,while11);
$$ = pai11;
}
;
ass : O ASS ID parameter F { h = process_line($3, h);
arvgen* pai12 = gcria("ass");
arvgen* o12 = gcria($1);
arvgen* ass12 = gcria($2);
arvgen* id12 = gcria($3);
arvgen* param12 = $4;
arvgen* f12 = gcria($5);
ginsere(pai12,f12);
ginsere(pai12,param12);
ginsere(pai12,id12);
ginsere(pai12,ass12);
ginsere(pai12,o12);
$$ = pai12;
}
;
funccall : O ID parameters F {
h = process_line($2, h);
arvgen* mfpai = gcria("functioncall");
arvgen* mffi1 = gcria($1);
arvgen* mffi2 = gcria($2);
arvgen* mffi3 = $3;
arvgen* mffi4 = gcria($4);
ginsere(mfpai,mffi4);
ginsere(mfpai,mffi3);
ginsere(mfpai,mffi2);
ginsere(mfpai,mffi1);
$$ = mfpai;
}
| O prefunc parameters F { arvgen* fccpai = gcria("functioncall");
arvgen* fccfi1 = gcria($1);
arvgen* fccfi2 = $2;
arvgen* fccfi3 = $3;
arvgen* fccfi4 = gcria($4);
ginsere(fccpai,fccfi4);
ginsere(fccpai,fccfi3);
ginsere(fccpai,fccfi2);
ginsere(fccpai,fccfi1);
$$ = fccpai;
}
;
prefunc : PREFUNC { arvgen* pfpai = gcria("prefunction");
arvgen* pffi1 = gcria($1);
ginsere(pfpai,pffi1);
$$ = pfpai;
}
|PRINT { arvgen* prpai = gcria("prefunction");
arvgen* prfi1 = gcria($1);
ginsere(prpai,prfi1);
$$ = prpai;
}
;
parameters : { $$ = gcria2(NULL); }
| parameters parameter { arvgen* pspai = gcria("parameters");
arvgen* psfi1 = $1;
arvgen* psfi2 = $2;
ginsere(pspai,psfi2);
ginsere(pspai,psfi1);
$$ = pspai;
}
;
parameter : funccall { arvgen* fcpai = gcria("parameter");
arvgen* fcfi1 = $1;
ginsere(fcpai,fcfi1);
$$ = fcpai;
}
| ID { h = process_line($1, h);
arvgen* idpai = gcria("parameter");
arvgen* idfi1 = gcria($1);
ginsere(idpai,idfi1);
$$ = idpai;
}
| number { arvgen* npai = gcria("parameter");
arvgen* nfi1 = $1;
ginsere(npai,nfi1);
$$ = npai;
}
| STRING { arvgen* spai = gcria("parameter");
arvgen* sfi1 = gcria($1);
ginsere(spai,sfi1);
$$ = spai;
}
| BOOL { arvgen* blpai = gcria("parameter");
arvgen* blfi1 = gcria($1);
ginsere(blpai,blfi1);
$$ = blpai;
}
;
number: INT {
char str[120];
arvgen* intpai = gcria("number");
sprintf(str,"%d",$1);
arvgen* intfi1 = gcria(str);
ginsere(intpai,intfi1);
$$ = intpai;
}
| FLOAT {
char str2[120];
arvgen* fpai = gcria("number");
sprintf(str2,"%f",$1);
arvgen* ffi1 = gcria(str2);
ginsere(fpai,ffi1);
$$ = fpai;
}
;
if : O IF exp THEN stms ELSE stms F {arvgen* ipai = gcria("if");
arvgen* ifi1 = gcria($1);
arvgen* ifi2 = gcria($2);
arvgen* ifi3 = $3;
arvgen* ifi4 = gcria($4);
arvgen* ifi5 = $5;
arvgen* ifi6 = gcria($6);
arvgen* ifi7 = $7;
arvgen* ifi8 = gcria($8);
ginsere(ipai,ifi8);
ginsere(ipai,ifi7);
ginsere(ipai,ifi6);
ginsere(ipai,ifi5);
ginsere(ipai,ifi4);
ginsere(ipai,ifi3);
ginsere(ipai,ifi2);
ginsere(ipai,ifi1);
$$ = ipai;
}
;
while : O WHILE exp DO stms F {arvgen* wpai = gcria("while");
arvgen* wfi1 = gcria($1);
arvgen* wfi2 = gcria($2);
arvgen* wfi3 = $3;
arvgen* wfi4 = gcria($4);
arvgen* wfi5 = $5;
arvgen* wfi6 = gcria($6);
ginsere(wpai,wfi6);
ginsere(wpai,wfi5);
ginsere(wpai,wfi4);
ginsere(wpai,wfi3);
ginsere(wpai,wfi2);
ginsere(wpai,wfi1);
$$ = wpai;
}
;
exp : O compoperation parameter parameter F { arvgen* copai = gcria("expression");
arvgen* cofi1 = gcria($1);
arvgen* cofi2 = $2;
arvgen* cofi3 = $3;
arvgen* cofi4 = $4;
arvgen* cofi5 = gcria($5);
ginsere(copai,cofi5);
ginsere(copai,cofi4);
ginsere(copai,cofi3);
ginsere(copai,cofi2);
ginsere(copai,cofi1);
$$ = copai;
}
| O booloperation exp exp F { arvgen* bopai = gcria("expression");
arvgen* bofi1 = gcria($1);
arvgen* bofi2 = $2;
arvgen* bofi3 = $3;
arvgen* bofi4 = $4;
arvgen* bofi5 = gcria($5);
ginsere(bopai,bofi5);
ginsere(bopai,bofi4);
ginsere(bopai,bofi3);
ginsere(bopai,bofi2);
ginsere(bopai,bofi1);
$$ = bopai;
}
| BOOL { arvgen* boolpai = gcria("expression");
arvgen* boolfi1 = gcria($1);
ginsere(boolpai,boolfi1);
$$ = boolpai;
}
;
compoperation : SYMBOL { arvgen* comppai = gcria("compoperation");
arvgen* compfi1 = gcria($1);
ginsere(comppai,compfi1);
$$ = comppai;
}
| SPECIAL { arvgen* specpai = gcria("compoperation");
arvgen* specfi1 = gcria($1);
ginsere(specpai,specfi1);
$$ = specpai;
}
;
booloperation : OR { arvgen* booloperation = gcria("booloperation");
arvgen* b1 = gcria($1);
ginsere(booloperation,b1);
$$ = booloperation;
}
| AND { arvgen* andpai = gcria("definitions");
arvgen* and1 = gcria($1);
ginsere(andpai,and1);
$$ = andpai;
}
;
%%
#include "lex.yy.c"
void display_hash(hash h)
{
int j;
for(j=0;j<7;j++)
{
printf("[%d]->",j);
display(h.index[j]);
printf("||\n");
}
}
int yyerror(char *s) { fprintf(stderr, "%s\n", s); }
int main(){
stk = push(stk, 0);
h = initialize_hash(h);
printf("--------------------Parse tree--------------------\n\n");
yyparse();
printf("\n\n--------------------Symbol table output-------------------- \n\n");
display_hash(h);
return 0;
}
這就是我如何編譯它:
flex hello.l
bison -dy hello.y
gcc lex.yy.c y.tab.c -o hello.exe
我得到的錯誤是:
In file included from FP.l:2:
FP.y:148: error: syntax error before "arvgen"
FP.y:148: warning: no semicolon at end of struct or union
FP.tab.h:85: warning: data definition has no type or storage class
FP.tab.h:91: error: syntax error before "yylval"
FP.tab.h:91: warning: data definition has no type or storage class
FP.l: In function `yylex':
FP.l:29: error: request for member `chari' in something not a structure or union
FP.l:30: error: request for member `chari' in something not a structure or union
FP.l:31: error: request for member `chari' in something not a structure or union
FP.l:32: error: request for member `chari' in something not a structure or union
FP.l:33: error: request for member `chari' in something not a structure or union
FP.l:34: error: request for member `chari' in something not a structure or union
FP.l:35: error: request for member `chari' in something not a structure or union
FP.l:36: error: request for member `chari' in something not a structure or union
FP.l:37: error: request for member `chari' in something not a structure or union
FP.l:38: error: request for member `chari' in something not a structure or union
FP.l:39: error: request for member `chari' in something not a structure or union
FP.l:40: error: request for member `chari' in something not a structure or union
FP.l:41: error: request for member `chari' in something not a structure or union
FP.l:42: error: request for member `chari' in something not a structure or union
FP.l:43: error: request for member `chari' in something not a structure or union
FP.l:44: error: request for member `chari' in something not a structure or union
FP.l:45: error: request for member `floati' in something not a structure or union
FP.l:46: error: request for member `inti' in something not a structure or union
FP.l:47: error: request for member `chari' in something not a structure or union
FP.l:48: error: request for member `chari' in something not a structure or union
FP.l:49: error: request for member `chari' in something not a structure or union
FP.l:50: error: request for member `chari' in something not a structure or union
我真的不能找到任何語法錯誤:( 所以我很迷失,現在,甚至儘管這段代碼在我的Linux分區正在運行...
開始解析第148行的第一個錯誤:arvgen –
在「arvgen」之前添加了一個「struct」,是其中的一個錯誤,謝謝 –