gpt4 book ai didi

c - Flex 和 Bison 逻辑运算符语法错误

转载 作者:行者123 更新时间:2023-11-30 16:10:55 32 4
gpt4 key购买 nike

我对 Flex 和 bison 很陌生,我正在做一个比较数字的应用程序。如果 a > b 将返回 0,a < b 将返回 1但是,当涉及到 &、|、== 时我遇到了问题这是我的输出示例:

>> a = 5

5

>> b = 8

8

>> a < b & a < b

1

>> syntax error

我不知道如何解决这个问题。以下是编译器的一些提示:

[tpham14@linux5 ~/331] make -f mymake calc
bison -d -o y.tab.c -v calc.y
calc.y: warning: 16 shift/reduce conflicts [-Wconflicts-sr]
calc.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
cc -c -o y.tab.o y.tab.c
cc -c -o lex.yy.o lex.yy.c
cc -o calc y.tab.o lex.yy.o

这是我的 calc.y 文件:

%{
#include "calc.h"
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

/************************************************************************
* Defines a yacc grammar for a simple calculator using infix
* notation. WHen executed, the calculator enters a loop in
* which it prints the prompt >>, reads a toplevel expression
* terminated by a newline, and prints its value. Operators
* include +, -, *, and = (assignment). Note that all
* expressions return values, even assignment. Parentheses
* can be used to override operator precedence and
* associativity rules. Based on zcalc by ruiz@capsl.udel.edu
************************************************************************/
int yylex();
int yyparse();

%}

/*
Th union directive specifies the collection of tpes our grammar
deals with -- just doubles and pointers to symbol table entries.
*/

%union {
double dval;
struct symtab *symp;
}

/*
Declare the token types and any associated value types. We made
EQ a token in calc.l because otherwise '=' and '==' would clash.
*/
%token <symp> NAME
%token <dval> NUMBER
%token EQ
%token GT
%token LT
%token OR
%token AND
%token NOT
%token IF
%token ELSE
/* The folowing declarations specify the precidence and associativity
of our operators. The operators -, +, * and / to be left
associative, * and EQ to be right associative and UMINUS to be
non-associative (since it is a unary operator). The '=' operator
has the lowest precedence and UMINUS the highest.
*/

%right '=' /*lowest precedence*/
%right EQ GT LT
%left '-' '+'
%left '*' '/'
%left '&'
%nonassoc OR AND NOT
%nonassoc IF
%nonassoc ELSE
%nonassoc UMINUS /* highest precedence */


/*
Declare the type of expression to be a dval (double).
*/

%type <dval> expr
%type <dval> smallexprs
%%

/*
Here are our grammar rules. a session is a sequence of lines. A
toplevel is just an expr (print its value followed by two
newlines and the prompt >>) or a '? (print help) or a '.' (exit).
An expr can be a number, name, the sum of two exprs, ...
*/

session: /* empty */
|session toplevel '\n'

;

toplevel: expr { printf("%g\n\n>> ", $1); }
| /*empty*/

| '?' { printHelp(); printf("\n>> "); }
| '.' { printf("Exiting 331 calc\n"); exit(1); }


expr: smallexprs { $$ = $1; }
| NAME { $$ = $1->value; }
| NAME '=' expr { $1->value = $3; $$ = $3; }
| IF expr expr expr { if($2 == 1) $$ = $3; else $$ = $4; }
| smallexprs AND smallexprs { $$ = $1 && $3; }
| smallexprs OR smallexprs { $$ = $1 || $3; }
| smallexprs EQ smallexprs { $$ = $1 == $3; }
| expr GT expr { $$ = $1 > $3; }
| expr LT expr { $$ = $1 < $3; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }

smallexprs: NUMBER { $$ = $1; }
| IF smallexprs smallexprs smallexprs { if($2 == 1) $$ = $3; else $$ = $4; }
| smallexprs EQ smallexprs { $$ = $1 == $3; }
| smallexprs GT smallexprs { $$ = $1 > $3; }
| smallexprs LT smallexprs { $$ = $1 < $3; }
| smallexprs '+' smallexprs { $$ = $1 + $3; }
| smallexprs '-' smallexprs { $$ = $1 - $3; }
| smallexprs '*' smallexprs { $$ = $1 * $3; }
| smallexprs '/' smallexprs { $$ = $1 / $3; }
| '~' smallexprs %prec UMINUS { $$ = -$2; }
| '(' smallexprs ')' { $$ = $2; }


%%

struct symtab *
symlook(s)
char *s;
{
char *p;
struct symtab *sp;

/* given the name of a symbol, scan the symbol table and
either return the entry with matching name or add it
to the next free cell in the symbol table. */

for(sp = symtab; sp < &symtab[SYMBOLTABLESIZE]; sp++) {

/* If the symbol table entry has a name and its equal
to the one we are looking for, return this entry */
if (sp->name && !strcmp(sp->name, s))
return sp;

/* If the name is empty then this entry is free, so the
symbol must not be in the table and we can add it here
and return this entry. */
if (!sp->name) {
sp->name = strdup(s);
return sp;
}
}

/* We searched the entire symbol table and neither found
the symbol or an unused entry. So the table must be
full. Sigh. */
yyerror("The symbol table is full, sorry...\n");
exit(1);
}



void printHelp()
{ /* print calculator help and return */
printf("Enter an expression in infix notation followed by a newline.\n");
printf("Operators include +, -, * and =. Defined functions include\n");
printf("sqrt, exp and log. You can assign a variable using the =\n");
printf("operator. Type . to exit. Syntax errors will terminate the\n");
printf("program, so be careful.\n");
}


/* If error prints error and Do not accept to signify bad syntax in
program */

void yyerror(char *msg) /* yacc error function */
{
printf("%s \n" , msg);
}

int yywrap(){return 1;}

int main()
{ /* print herald and call parser */
printf("331 Calculator\n(type ? for help and . to exit)\n\n>> ");
yyparse();
return 0;
}

下面是我的 calc.l 文件:

%{
#include "y.tab.h"
#include "calc.h"
#include <math.h>

/************************************************************************
A lexical scanner to recognize numbers, symbols and the EQ
operator. When a NUMBER is found, its value is set is set to the
appropriate float. When a NAME is found, an entry in symbol table is
created (with initial value 0.0) and the token's value is a pointer to
this entry. If a '==' sequence is seen, it is returned as a token
EQ. Spaces and tabs are ignored. Any other characters, including
a newline, are passed on as their own tokens. Based on the zcalc
calculator by ruiz@capsl.udel.edu
************************************************************************/

%}

D [0-9]
A [a-zA-Z]
AD [a-zA-Z0-9]

%%

({D}+|({D}*\.{D}+)([eE][-+]?{D}+)?) {yylval.dval = atof(yytext); return NUMBER;}

if {return IF;}
or {return OR;}
and {return AND;}
not {return NOT;}



{A}{AD}* {struct symtab *sp = symlook(yytext); yylval.symp = sp; return NAME;}

"==" {return EQ;}
">" {return GT;}
"<" {return LT;}
[ \t] ;

\n |
. return yytext[0];

%%

下面是我的 calc.h 文件:

#define SYMBOLTABLESIZE 30

/* An entry in the symbol table has a name, a pointer to a function,
and a numeric value. */

struct symtab {
char *name;
double (*funcptr)();
double value;
} symtab[SYMBOLTABLESIZE];

struct symtab *symlook();

void printHelp();
void yyerror();

最佳答案

语法错误没有规则匹配或包含&

&& 标记在您的 lex 规范中定义为“and”,您应该检查

 a < b and a < b

或将 lex 规范更改为

  &&     { return AND;}
|| { return OR;}
! { return NOT;}

GT 移位后,减少 Px 作为小表达式跟随包含 GT类似地,LT、+、-、*。 (6 转移/减少冲突)

 expr:   smallexprs                  --- Px
smallexprs: smallexprs .GT smallexprs ---Sy



expr: smallexprs EQ smallexprs .
smallexprs: smallexprs EQ smallexprs .

减少/减少expr和smallexprs的Follow冲突(6个减少/减少冲突)

关于c - Flex 和 Bison 逻辑运算符语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58780417/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com