首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Bison Stack赋值

Bison Stack赋值
EN

Stack Overflow用户
提问于 2014-09-05 14:44:59
回答 1查看 47关注 0票数 0

这是一个使用Flex的词法分析器。

代码语言:javascript
运行
复制
#include <iostream> 
#include <cstdio>

#define YY_DECL extern "C" int yylex()

#include "conv.tab.h"
using namespace std;

%}
eq [ \t]*=
%%

[ \t]           ;
(?:POINT|LINE)  { yylval.ename = strdup(yytext); return ENAME; }
x{eq}           { yylval.xval = atof(yytext);
                    return XVAL; }
y{eq}           { yylval.yval = atof(yytext);
                    return YVAL; }
.               ;
%%

和其他文件是Bison语法文件

代码语言:javascript
运行
复制
%{
#include <iostream>
#include <cstdio>
#include <stdio.h>
using namespace std;

extern "C" int yylex ();
extern "C" int yyparse (void);
extern "C" FILE *yyin;
extern int line_no;

void yyerror(const char *s);

%}

%union{
    float xval;
    float yval;
    char *ename;
}

%token <ename> ENAME
%token XVAL
%token YVAL

%%

converter:
    converter ENAME { cout << "entity = " << $2 << endl; }
    | converter XVAL {// x -> xval = $2; 
      cout << "x value = " << endl; }
    | converter YVAL {// y -> yval = $2; 
       cout << "y value = " << endl; }
    | ENAME { cout << "entity = " << $1 << endl; }
    | XVAL { cout << "xvalue " << endl; }
    | YVAL { cout << "yvalue " << endl; }

%%
main() {
    FILE *myfile = fopen("conv.aj", "r");

    if (!myfile) {
            cout << "I can't open file" << endl;
            return -1;
    }

    yyin = myfile;

    do{
            yydebug = 1;
            yyparse();
    } while (!feof(yyin));
    yydebug = 2;
}

void yyerror(const char *s) {
    cout << "Parser error! Message: " << s << endl;
    exit(-1);
}

实际上,我想从文件中检索值。我使用了Bison调试器,并了解到这些值无法推送到Bison Stack。所以基本上我想把这些值推送到stack.My文件中,就像这样: POINT x=38 y=47

EN

回答 1

Stack Overflow用户

发布于 2014-09-05 23:30:45

您的词法分析器中没有与数字匹配的内容,因此输入中的3847都将由您的默认规则(. ;)处理,这将导致它们被忽略。在XVALYVAL的规则中,您在yytext上调用atoi,它将是x= (或y=);这显然不是一个数字,atoi可能会返回0

我不清楚您所说的“这些值不能推入Bison Stack”是什么意思,但我认为这个问题与bison或它的堆栈无关。

顺便说一下:

  1. 没有必要在xvalyval的语义类型中有两个不同的成员。该类型是一个union,而不是一个struct,所以拥有两个相同类型(float)的成员是不会执行正则表达式捕获的。因此,避免使用(?:...)进行捕获是没有意义的;它只会模糊您的语法。你也可以使用:

POINT|LINE:{ yylval.ename = strdup(yytext);return ENAME;}

另一方面,您最好定义两种不同的令牌类型,这样可以避免对strdup的需要。(您似乎没有对重复的字符串执行free操作,因此strdup也是一个内存泄漏。)或者,您可以在语义类型中使用枚举值:

POINT { yylval.ename_enum=POINT;return ENAME;}行{ yylval.ename_enum=LINE;return ENAME;}

  • . ;实际上不是一个好主意,特别是在开发期间,因为它会隐藏错误(比如您有的错误)。你可以使用%option nodefault来避免flex的默认规则,然后当一个非法的字符是flex时,flex会显示一个错误。如果你使用的是非常旧的bisonflex版本,你可以将生成的代码编译成c++
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25680020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档