简体   繁体   English

Flex / Bison不断给我语法错误

[英]Flex/bison keeps on giving me syntax error

i'm trying to make a mini compiler using lex and yacc however each time i try to test my parser i keep getting a syntax error. 我正在尝试使用lex和yacc制作一个小型编译器,但是每次尝试测试解析器时,我都会收到语法错误。

Here is my lex file : 这是我的lex文件:

%option noyywrap
%{
    #include "y.tab.h"
    int line = 1;
    int spaceCount = 1;
    int sourceLineCount = 1;
%}

IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
WHITESPACE [ ]
DIGIT [0-9]
TAB \t
NEXTLINE \n

%%
int return INT;
float   return FLOAT;
double  return DOUBLE;
char    return CHAR;
void    return VOID;

static  return STATIC;
const   return CONST;

struct  return STRUCT;
union   return UNION;
enum    return ENUM;

if  return IF;
else    return ELSE;
switch  return SWITCH;
case    return CASE;

break   return BREAK;
default return DEFAULT;

^"#include ".+ ;
typedef return TYPEDEF;
extern  return EXTERN;

for return FOR;
while   return WHILE;
do  return DO;


"<" return LT;
">" return GT;
"<="    return LE;
">="    return GE;
"=="    return EQ;
"!="    return NE;


"." return DOT;
"," return COMMA;

printf return PRINTF;

return  return RETURN;

{DIGIT}+       return NUM;



{NEXTLINE} {
    line++;
}
{WHITESPACE} {
    spaceCount++;
}
.       return yytext[0];
%%

And my yacc/bison file : 还有我的yacc / bison文件:

%{
    #include<stdio.h>
    extern FILE *fp;
%}

%token INT FLOAT CHAR DOUBLE VOID
%token FOR WHILE DO
%token IF ELSE PRINTF
%token STRUCT ENUM UNION
%token SWITCH CASE BREAK DEFAULT
%token NUM ID
%token INCLUDE
%token DOT COMMA
%token STATIC CONST
%token TYPEDEF EXTERN
%token RETURN
%right '='
%left AND OR
%left '<' '>' LE GE EQ NE LT GT




%% 
start:  Function 
    | Declaration
    ;

/* DECCLARATION */
Declaration: Type Assignment ';' 
    | Assignment ';'    
    | FunctionCall ';'  
    | ArrayUsage ';'    
    | Type ArrayUsage ';'   
    | StructStmt ';'    
    | error 
    ;

/* ASSIGNMENT */
Assignment: ID '=' Assignment
    | ID '=' FunctionCall
    | ID '=' ArrayUsage
    | ArrayUsage '=' Assignment
    | ID ',' Assignment
    | NUM ',' Assignment
    | ID '+' Assignment
    | ID '-' Assignment
    | ID '*' Assignment
    | ID '/' Assignment 
    | NUM '+' Assignment
    | NUM '-' Assignment
    | NUM '*' Assignment
    | NUM '/' Assignment
    | '\'' Assignment '\''  
    | '(' Assignment ')'
    | '-' '(' Assignment ')'
    | '-' NUM
    | '-' ID
    |   NUM
    |   ID
    ;

/* Function Call*/
FunctionCall : ID'('')'
    | ID'('Assignment')'
    ;
/* Function block */
Function: Type ID '(' ArgListOpt ')' CompoundStmt 
    ;
ArgListOpt: ArgList
    |
    ;
ArgList:  ArgList ',' Arg
    | Arg
    ;
Arg:    Type ID
    ;

/* Array Usage */
ArrayUsage : ID'['Assignment']'
    ;

CompoundStmt:   '{' StmtList '}'
    ;
StmtList:   StmtList Stmt
    |
    ;
Stmt:   WhileStmt
    | Declaration
    | ForStmt
    | IfStmt
    | PrintFunc
    | SwitchStmt
    | ';'
    ;

/* Type Identifier block */
Type:   INT 
    | FLOAT
    | CHAR
    | DOUBLE
    | VOID 
    ;

/* Loop Blocks */ 
WhileStmt: WHILE '(' Expr ')' Stmt  
    | WHILE '(' Expr ')' CompoundStmt 
    ;

/* For Block */
ForStmt: FOR '(' Expr ';' Expr ';' Expr ')' Stmt 
       | FOR '(' Expr ';' Expr ';' Expr ')' CompoundStmt 
       | FOR '(' Expr ')' Stmt 
       | FOR '(' Expr ')' CompoundStmt 
    ;

/* IfStmt Block */
IfStmt : IF '(' Expr ')' 
        Stmt 
    ;
/* SwitchStmnt */
SwitchStmt  : SWITCH '(' ID ')'
        CaseStmt
          | SWITCH '(' ID ')'
        CompoundStmt
        CaseStmt
        DefaultStmt
        ;
/* CaseStmt */
CaseStmt    : CASE NUM ':'
        Stmt
        BREAK ';'
        ;
/* DefaultStmt */
DefaultStmt  : DEFAULT ':'
        Stmt
        BREAK ';'
/* Struct Statement */
StructStmt : STRUCT ID '{' Type Assignment '}'  
    ;

/* Print Function */
PrintFunc : PRINTF '(' Expr ')' ';'
    ;
/*Expression Block*/
Expr:   
    | Expr LE Expr 
    | Expr GE Expr
    | Expr NE Expr
    | Expr EQ Expr
    | Expr GT Expr
    | Expr LT Expr
    | Assignment
    | ArrayUsage
    ;


%%
#include"lex.yy.c"
#include<ctype.h>
int count=0;

int main(int argc, char *argv[])
{
   yyin = fopen(argv[1], "r");

   if(!yyparse())
        printf("\nParsing complete\n");
    else
        printf("\nParsing failed\n");

    fclose(yyin);
    return 0;
}

yyerror(char *s) {
    printf("\n %d: %s avant %s\n\n",line,s, yytext );
} 

I tried to test it with multiple test files but it always seems to give me a syntax error, here is a sample of what i tried. 我尝试使用多个测试文件对其进行测试,但它似乎总是给我带来语法错误,这是我尝试过的示例。

int main()
{
   int a;
}

in this case i got an error before "m". 在这种情况下,我在“ m”之前出现错误。

Nowhere in your lexical scanner do you 您在词法扫描器中无处可做

return ID;

which means that productions in the parser which require an ID token are never going to match anything. 这意味着解析器中需要ID令牌的产品永远不会匹配任何内容。 I suppose you just forgot to add the line which recognises identifiers. 我想您只是忘了添加识别标识符的行。 Note that main should be an ID , which is why your parse fails at that point. 请注意, main应该是一个ID ,这就是为什么此时解析失败的原因。

There are other problems with your grammar, including the fact that it only recognizes a single function declaration ( Function ) or other statement ( Declaration ). 语法还有其他问题,包括它仅识别单个函数声明( Function )或其他语句( Declaration )的事实。 Along with any other changes you make, you should try to give your non-terminals more meaningful names, so that other people can understand your grammar. 除了进行其他更改外,还应尝试给非终结符赋予更有意义的名称,以便其他人可以理解您的语法。 (This might help you, too.) (这也可能对您有帮助。)

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

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