2017-02-05 91 views
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分區正在運行...

+0

開始解析第148行的第一個錯誤:arvgen –

+0

在「arvgen」之前添加了一個「struct」,是其中的一個錯誤,謝謝 –

回答

0

的問題是,arvgen只在野牛來源定義;它沒有被定義在由flex生成的文件可見的任何地方。

您可以將arvgen的聲明放在一個單獨的頭文件中,並將它包含在flex和bison prolog中。或者,您可以使用野牛的%code requires塊將其放入由野牛產生的頭中。