gpt4 book ai didi

c - 柔性/Bison : yytext skips over a value

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

我花了两天的时间绞尽脑汁试图找出程序为什么会这样。对于一个类(class)项目,我正在尝试编写一个程序来解析地址并以某种方式输出它。在我真正到达程序的输出部分之前,我只是想确保我的 Bison-fu 实际上是正确的并正确输出一些调试信息。

看起来 Flex 和 Bison 合作得很好,正如预期的那样,但由于某种原因,当我解析地址的第三行时,yytext 只是跳过邮政编码并直接转到新行。

下面是我测试过的 Flex 和 Bison 文件的精简版本,仍然输出与完整版本相同的内容:

[19:45]<Program4> $ cat scan.l
%option noyywrap
%option nounput
%option noinput

%{
#include <stdlib.h>
#include "y.tab.h"
#include "program4.h"
%}

%%

[\ \t]+ { /* Eat whitespace */}
[\n] { return EOLTOKEN; }
"," { return COMMATOKEN; }
[0-9]+ { return INTTOKEN; }
[A-Za-z]+ { return NAMETOKEN; }
[A-Za-z0-9]+ { return IDENTIFIERTOKEN; }

%%

/*This area just occupies space*/
[19:45]<Program4> $ cat parse.y


%{
#include <stdlib.h>
#include <stdio.h>
#include "program4.h"

%}

%union {int num; char id[20]; }
%start locationPart
%expect 0
%token <num> NAMETOKEN
%token <num> EOLTOKEN
%token <num> INTTOKEN
%token <num> COMMATOKEN
%type <id> townName zipCode stateCode

%%

/* Entire block */
locationPart: townName COMMATOKEN stateCode zipCode EOLTOKEN
{ printf("Rule 12: LP: TN COMMA SC ZC EOL: %s\n", yytext); }
| /* bad location part */
{ printf("Rule 13: LP: Bad location part: %s\n", yytext); }
;

/* Lil tokens */
townName: NAMETOKEN
{ printf("Rule 23: TN: NAMETOKEN: %s\n", yytext); }
;

stateCode: NAMETOKEN
{ printf("Rule 24: SC: NAMETOKEN: %s\n", yytext); }
;

zipCode: INTTOKEN DASHTOKEN INTTOKEN
{ printf("Rule 25: ZC: INT DASH INT: %s\n", yytext); }
| INTTOKEN
{ printf("Rule 26: ZC: INT: %s\n", yytext); }
;

%%

int yyerror (char const *s){
extern int yylineno; //Defined in lex

fprintf(stderr, "ERROR: %s at symbol \"%s\"\n at line %d.\n", s, yytext,
yylineno);
exit(1);
}
[19:45]<Program4> $ cat addresses/zip.txt
Rockford, HI 12345
[19:45]<Program4> $ parser < addresses/zip.txt
Operating in parse mode.

Rule 23: TN: NAMETOKEN: Rockford
Rule 24: SC: NAMETOKEN: HI
Rule 26: ZC: INT:

Rule 12: LP: TN COMMA SC ZC EOL:

Parse successful!
[19:46]<Program4> $

正如您在底部附近看到的,它打印 Rule 26: ZC: INT: 但无法打印 5 位邮政编码。就像程序只是跳过数字并存储换行符一样。知道为什么它不存储和打印邮政编码吗?

注释:

  • yytext 在我的 .h 文件中被定义为 extern(此处未发布);
  • 我正在使用 -vdy 标志来编译 parse.c 文件

最佳答案

如果您想跟踪解析器的工作情况,最好启用 bison 的跟踪功能。这真的很容易。只需添加 -t--debug标记为bison命令生成代码,然后添加一行以实际生成跟踪:

/* This assumes you have #included the parse.tab.h header */
int main(void) {
#if YYDEBUG
yydebug = 1;
#endif

这在 the Bison manual 中有解释。 ; #if如果您省略 -t 让您的程序编译旗帜。关于标志的主题,我强烈建议您不要使用 -y旗帜;它用于编译依赖于某些过时功能的旧 Yacc 程序。如果您不使用-y ,然后 bison 将使用你的 .y 的基名扩展名为 .tab.c 的文件和.tab.h对于生成的文件。

现在,您的 bison 文件表明您的某些标记具有语义类型,但您的 Flex 操作没有为这些标记设置语义值,并且您的 bison 操作不使用语义值。相反,您只需打印 yytext 的值即可。 。如果您稍微思考一下,您应该能够明白为什么它不起作用。 Bison 是一个前瞻解析器;它根据当前解析状态和查看下一个标记(如果需要)做出解析决策。它通过调用词法分析器来查看下一个标记。当您调用词法分析器时,它会更改 yytext 的值.

Bison(与其他 yacc 实现不同)并不总是查看下一个标记。但在您的邮政编码规则中,它别无选择,因为它无法判断下一个标记是否是 -或者不看它就不会。在本例中,它不是破折号;而是破折号。这是一个换行符。那么你猜怎么着yytext当您在邮政编码操作中打印出来时包含。

如果您的分词器要将文本保存在 id 中语义值成员(这就是它的用途),那么您的解析器将能够访问语义值 $1 , $2 ,...

关于c - 柔性/Bison : yytext skips over a value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49331561/

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