Flex/Bison:yytext跳过一个值 [英] Flex/Bison: yytext skips over a value

查看:78
本文介绍了Flex/Bison:yytext跳过一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经花了两天的时间试图弄清楚该程序为何采用这种方式.对于一个类项目,我试图编写一个解析地址并以某种方式输出地址的程序.在我真正进入程序的输出部分之前,我只想确保Bison-fu实际上是正确的,并正确输出一些调试信息.

I've been racking my brain for two days trying to figure out why the program is behaving this way. For a class project, I'm trying to write a program that parses an address and outputs it a certain way. Before I actually get to the output portion of the program, I just wanted to make sure my Bison-fu was actually correct and outputting some debugging information correctly.

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

It looks as if Flex and Bison are cooperating with each other nicely, as expected, but for some reason, when I get to the parsing of the third line of the address, yytext just skips over the zip code and goes straight to the new line.

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

Below is a stripped down version of my Flex and Bison files that I tested and still outputs the same thing as the full version:

[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> $

如您在底部附近看到的那样,它会打印规则26:ZC:INT:,但无法打印5位数的邮政编码.就像程序只是跳过数字并存储换行符一样.有什么想法为什么它不存储和打印邮政编码?

As you can see near the bottom, it prints Rule 26: ZC: INT: but fails to print the 5 digit zip code. It's like the program just skips the number and stores the newline instead. Any ideas why it won't store and print the zip code?

注意:

  • yytext在我的.h文件中定义为外部元素(不在此处发布);
  • 我正在使用 -vdy 标志来编译parse.c文件
  • yytext is defined as an extern in my .h file (not posted here);
  • I am using the -vdy flags to compile the parse.c file

推荐答案

由于 yytext 是全局变量,因此已被覆盖,因此您必须将其复制到 lex 中脚本.在纯解析器中,即使它不再是全局的,它仍然可以重用并作为参数传递,因此像您尝试的那样使用它的值是不正确的.

Because yytext is a global variable, it's overwritten and you will have to copy it in your lex script. In a pure parser, even though it's not global anymore it's still reused and passed as a parameter so it's incorrect to use it's value like you are attempting.

此外,请勿在野牛中使用它,而应使用 $ n ,其中 n 是标记在规则中的位置.您可能需要将%union 指令更改为类似的

Also, don't use it in bison, instead use $n where n is the position of the token in the rule. You probably need the %union directive changed to something like

%union {
    int number;
    char *name;
};

因此在 flex 文件中,如果要捕获文本,请执行类似的操作

So in the flex file, if you want to capture the text do something like

[A-Za-z]+               { yylval.name = strdup(yytext); return NAMETOKEN; }

请记住,不要在 bison 中使用 yytext ,这是词法分析器使用的内部工具.

and remember, do not use yytext in bison, it's an internal thing used by the lexer.

然后,由于您已经定义了邮政编码的类型

Then and since you have defined a type for the zip code

/* Entire block */
locationPart:           townName COMMATOKEN stateCode zipCode EOLTOKEN {
    printf("Rule 12: LP: TN COMMA SC ZC EOL: town:%s, stateCode:%d zip-code:%s\n", $1, $3, $4); 
}

这篇关于Flex/Bison:yytext跳过一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆