首页 > 解决方案 > 查找 Flex Yacc 中发生语法错误的位置

问题描述

我对 lex 和 yacc 很陌生。

我正在设计一个可以制作三地址代码的编译器。

如何找到代码中发生语法错误的位置?

进入后:

flex lexer.l
bison -dy parser.y
gcc lex.yy.c y.tab.c -o program.exe

我试试这个输入:

{ int abc = 234 ; }

然后它给了我语法错误!

我该如何解决?

这是我的词法分析器

词法分析器.l:

%{

#include "y.tab.h"
#include <string.h>
int yyerror(char *errormsg);

%}

letter  [a-zA-z]
digit   [0-9]
id      {letter}({letter}|{digit})*
ws      [ \t]


%%
{ws}        ;
\{          { return 300; }
\}          { return 301; }
\;          { return SEMICOLON; }
"if"        { return IF; }
"int"       { return INT; }
"float"     { return FLOAT; }
"char"      { return CHAR; }
\=          { return ASSIGN; }      
{id}        {strcpy(yylval.str,yytext) ; return ID; }
{digit}+    {yylval.ival=atoi(yytext); return NUMBER; }
.           {yyerror("Invalid Command");}
%%



int main(void)
{
   yyparse();
   printf("DONE");
   return 0;
}

int yywrap(void)
{
   return 0;
}

int yyerror(char *errormsg)
{
    fprintf(stderr, "hey!%s\n", errormsg);
    exit(1);
}

这是我的解析器

解析器.y:

%{

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int yylex(void);
int yyerror(const char *s);

%}


%union{int ival; double dval; char str[120]; }

%token INT ASSIGN NUMBER IF SEMICOLON
%token FLOAT
%token ID CHAR

%%

Program: 
        Block
        ;

Block:
        '{' Stmts '}'
        ;

Stmts:
        Stmts Stmt
        | Stmt
        ;

Stmt:
        Block
        |IfStmt
        |AssignStmt
        |DeclStmt
        ;


IfStmt:
        IF '(' Expr ')' Stmt  { printf("if found"); }
        ;


AssignStmt:     
        Type ID ASSIGN Expr SEMICOLON { printf("int found!"); }
        ;

DeclStmt:
        Type ID SEMICOLON
        ;


Type:
        INT
        |FLOAT
        |CHAR
        ;


Expr:
    NUMBER
    ;

标签: compiler-constructionbisonyacclex

解决方案


你可以通过编译来让野牛输出它正在做的事情-DYYDEBUG=1'

gcc -DYYDEBUG=1 lex.yy.c y.tab.c -o program.exe

然后将yydebug全局变量设置为真值运行:

int main(void)
{

    #ifdef YYDEBUG
    yydebug = 1;
    #endif
   yyparse();
   printf("DONE");
   return 0;
}

为您的项目执行此操作,产量

Starting parse
Entering state 0
Reading a token: Next token is token $undefined ()
hey!syntax error

IOW,词法分析器返回的第一个标记未被解析器识别。

您正在返回300for {,但解析器期望'{',因此只需修复词法分析器规则:

//WRONG
\{          { return 300; }
\}          { return 301; }

//OK
 \{          { return '{'; }
 \}          { return '}'; }

然后你得到一个完成的解析,虽然一个挂起。

挂起是由您返回造成0yywrap。将其更改为1将删除它。


推荐阅读