简体   繁体   English

Windows上的lex / yacc出现问题

[英]Trouble with lex/yacc on windows

I'm trying to make my own compiler using lex/yacc, there are only two codes and I'm specting it to run just like this (without extra headers right now). 我正在尝试使用lex / yacc制作自己的编译器,只有两个代码,并且我希望它像这样运行(现在没有额外的头文件)。

So this is my lex file (FP.l): 这是我的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; }

And this is my yacc file (FP.y): 这是我的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;
}

And that's how I'm compiling it: 这就是我的编译方式:

flex hello.l
bison -dy hello.y
gcc lex.yy.c y.tab.c -o hello.exe

The error I'm getting is the following: 我收到的错误如下:

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

I can't really find any syntax error :( So I'm pretty lost right now, even tho this code was running in my linux partition... 我真的找不到任何语法错误:(因此,即使这段代码正在我的linux分区中运行,我现在也很迷路...

The problem is that arvgen is only defined in the bison source; 问题在于, arvgen仅在野牛源中定义; it is not defined anywhere which is visible for the file generated by flex. 在flex生成的文件可见的任何地方都没有定义它。

You can put the declaration of arvgen in a separate header file and #include it in both the flex and bison prologs. 您可以将arvgen声明放在单独的头文件中,并在flex和bison序言中将其#include包括在内。 Or you can use bison's %code requires block to put it in the header generated by bison. 或者,您可以使用野牛的%code requires块将其放入野牛生成的标头中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM