gpt4 book ai didi

c - 简单计算器的词法分析器和语法的意外行为

转载 作者:行者123 更新时间:2023-11-30 17:09:27 27 4
gpt4 key购买 nike

我正在开始了解 Flex 和 Bison 的整个世界。所以我按照教程为 Flex 编写了这个 l 文件:

%{
#include <stdio.h>
#include <stdlib.h>
void yyerror(char *);
#include "y.tab.h"
%}

%%

/******************** RULES ********************/

/* One letter variables */
[a-z] {
yylval = *yytext - 'a'; // This is to return a number between 0 and 26 representting the letter variable.
printf("VAR: %s\n",yytext);
return VARIABLE;
}

/* Integer constants */
[0-9]+ {
yylval = atoi(yytext);
printf("INT: %d\n",yylval);
return INTEGER;
}

/* Operators */
[-+()=/*\n]+ { printf("OPR: %s\n",yytext); return *yytext; /*\n is considered an operator because it signals the end of a statement*/ }

/* This skips white space and tab chararcters */
[ \t] ;


/* Anything esle is not allowed */
. yyerror("Invalid character found");

/***************** SUBROUTINES *****************/
%%

int yywrap(void){
return 1;
}

这是语法:

/***************** DEFINITIONS *****************/

%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'

%{
void yyerror(char *);
int yylex(void);
int sym[26];
%}

%%
/******************** RULES ********************/

program:
program statement '\n'
|
;

statement:
expr { printf("EXPR: %d\n", $1); }
| VARIABLE '=' expr { sym[$1] = $3; }
;
expr:
INTEGER
| VARIABLE { $$ = sym[$1]; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '(' expr ')' { $$ = $2; }
;
%%
/***************** SUBROUTINES *****************/
void yyerror(char *s){
printf("%s\n",s);
}

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

出现了一些问题。第一个是编译时出现的。这就是我的编译方式:

bison -d bas.y -o y.tab.c
flex bas.l
gcc y.tab.h lex.yy.c y.tab.c -o bas_fe

这给了我两个这样的警告:

bas.y:24:7: warning: incompatible implicit declaration of built-in function ‘printf’
expr { printf("EXPR: %d\n", $1); }
^
bas.y: In function ‘yyerror’:
bas.y:39:4: warning: incompatible implicit declaration of built-in function ‘printf’
printf("%s\n",s);

现在,它们是警告和打印工作,但我发现这很奇怪,因为我已经明确包含了使用 printf 函数的库。

我真正的问题来自于我与程序的交互。这是控制台输出:

x = (3+5)
VAR: x
OPR: =
OPR: (
INT: 3
OPR: +
INT: 5
x
OPR: )

VAR: x
syntax error

由此产生了几个问题。1) 当输入 x = (3+5) 时,程序打印输出不包含 ')' 为什么?

2) 当输入x(预期输出为8)时,才会出现“)”。为什么?

3) 然后出现“语法错误”消息。我假设该消息是在 y.tab.c 的代码中自动生成的。能不能改成更有意义的东西?我是否正确地假设语法错误是因为程序找到了 ) 和换行符以及变量,并且这与语法定义的程序语句不对应?

最佳答案

I have clearly included the libraries for use of the printf function.

You included stdio.h in your flex file, but not in your bison file. And the warnings about printf being undeclared are from your bison file, not your flex file.

当您使用 gcc(或任何其他 C 编译器)编译多个文件时,这些文件将独立编译,然后链接在一起。所以你的命令

gcc y.tab.h lex.yy.c  y.tab.c -o bas_fe

不会连接三个文件并将它们编译为一个单元。相反,它独立编译这三个文件,包括无用地编译头文件 y.tab.h .

您应该做的是添加一个序言 block ,包括 #include <stdio.h>给您bas.y文件。

[-+()=/*\n]+ {... return *yytext; ...}

此弹性模式匹配 [-+()=/*\n] 集中任意数量的字符。所以在输入x=(3+5)\n)\n正在作为单个标记进行匹配。但是,该操作返回 *yytextyytext 的第一个字符,有效地忽略 \n 。因为你的语法需要 \n ,这会产生语法错误。

只需从模式中删除重复运算符即可。

可以将错误消息更改为更有意义的内容吗?

如果您有一头相当现代的 Bison ,请添加声明

%error-verbose

到 bison 文件的开头。

关于c - 简单计算器的词法分析器和语法的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33278563/

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