解析器错误 1:yacc 语法错误

问题描述 投票:0回答:1

我在 yacc (bison) 中有一个简单的语法:

表达式.y:

%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../C_routines/SyntaxTree.h"

extern int yylineno;

int yylex();
void yyerror(const char *s);
int i=0;

typedef struct Exp {
    char *code;
    char *addr;
} Exp;
%}

%union {
    char *lexeme;
    char *value;
    double dvalue;
    struct SyntaxTree *Sy;
    int ivalue;
}

%type <Sy> E S
%token <lexeme> id ID 
%token <value> LITERAL
%token <dvalue> FLOAT
%token <ivalue> INT

%left '+' '-'
%left UMINUS

%%

S : id "=" E { $$ = newST('=',newid($1), $3); printSyntaxTree($$); }
  ;

E : E "+" E { $$ = newST('+', $1, $3); }
  | E "-" E { $$ = newST('-', $1, $3); }
  | "(" E ")" { $$ = $2; }
  | "-" E %prec UMINUS { $$ = newST(UMINUS, NULL, $2); }
  | id { $$ = newid($1); }
  | INT { $$ = newint($1); }
  | FLOAT { $$ = newdouble($1); }
  ;

%%

void yyerror(const char *s) {
    fprintf(stderr, "Parser error at %d: %s\n", yylineno, s);
}

int main() {
    yyparse();
    return 0;
}

莱克斯:

%option yylineno

%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../yacc/expressions.tab.h"
#include "../C_routines/SymbolTable.h"

%}

id [a-zA-Z_][a-zA-Z_0-9]*

INT [-]?[0-9]+
FLOAT [-]?[0-9]+([.][0-9]+)?([Ee][+-]?[0-9]+)?
bool "True" | "False"
str (\"([^\"\\\\]|\\\\.)*\")|('([^'\\\\]|\\\\.)*')

assign [+-/%*]?=
arith [+-/%*]


%%

{id} {
    printf("\nIdentifier : %s ", yytext);
    int a = installID(yytext, "ID");
    yylval.lexeme = strdup(yytext);
    return id;
}

{INT} {printf("\nInteger : %s ",yytext);
      int a = installLit(yytext,"INT");
      yylval.value = strdup(yytext);
      return INT;}

{str} {printf("String ");
      int a = installLit(yytext,"STR");
      yylval.value = strdup(yytext);
      return LITERAL;}

{FLOAT} {printf("Float ");
      int a = installLit(yytext,"FLOAT");
      yylval.value = strdup(yytext);
      return FLOAT;}

{assign} {printf("Assignment Operator\n");}
{arith} {printf("Arithmetic Operator\n");}


%%

int yywrap(){
  return 1;
}

当我运行这些时:

输出1

a=0

Identifier : a Assignment Operator

Integer : 0 Parser error at 1: syntax error

输出2


a=b

Identifier : a Assignment Operator

Identifier : b Parser error at 1: syntax error

输出3

a=-4

Identifier : a Assignment Operator

Integer : -4 Parser error at 1: syntax error

输出4:

a=5+6

Identifier : a Assignment Operator

Integer : 5 Parser error at 1: syntax error

我已经为操作符和终端定义了足够的优先级和关联性。 我无法弄清楚是什么导致了第 1 行中的语法错误。请帮忙。我使用 flex 作为 lex,使用 bison 作为 yacc

编辑:在声明部分添加

#define YYERROR_VERBOSE 1
给出,

输出1:

a=0

Identifier : a Assignment Operator

Integer : 0 Parser error at 1: syntax error, unexpected INT, expecting =

输出2:

a=a+b

Identifier : a Assignment Operator

Identifier : a Parser error at 1: syntax error, unexpected id, expecting =

输出3:

a = b

Identifier : a  Assignment Operator

Identifier : b Parser error at 1: syntax error, unexpected id, expecting =

我在输入中给出了

=
,但它再次要求=符号

yacc
1个回答
0
投票

Bison 说它没有按预期收到“=”,而且它没有撒谎。 查看词法分析器。该规则打印“赋值运算符”,从不返回任何内容。从解析器的角度来看,那里什么也没有。

由于这些原因,使用

printf

 进行调试是不可靠的。您应该使用
正确的方法来调试您的词法分析器和解析器。

© www.soinside.com 2019 - 2024. All rights reserved.