【问题标题】:Change yyin to argv[1] Flex & Bison将 yyin 更改为 argv[1] Flex & Bison
【发布时间】:2016-11-15 18:29:01
【问题描述】:

我正在从事一个 Flex & Bison 项目。我的 flex & bison 工作正常,但我试图将 argv 作为输入(yyin)。所以我改变了 yyin 以便它使用 argv[1] 但它实际上不起作用。似乎它使用了 argv[1] 但随后我得到了一个语法错误,即使我的字符串我认为可以正常工作。

这是我的弹性:

%{
#include "parser.hpp"
extern int yyparse();
%}

%option noyywrap


texte  [a-zA-z]+
entier [0-9]+(\.[0-9])?

%%

{entier} { yylval.num = atoi(yytext); return(NUMBER);}

"pi" return(PI);
"," return(SEP);
"(" return(OP);
")" return(CP);
"+" return(ADD);
"-" return(SUB);
"*" return(MUL);
"/" return(DIV);
"%" return (MODULO);
"sin" return(SIN);
"cos" return(COS);
"tan" return(TAN);
"acos" return(ACOS);
"asin" return(ASIN);
"atan" return(ATAN);
"sqrt" return(ROOT);
"pow" return(POW);
"exp" return(EXP);
"\n" return(END);
{texte} return(ERROR);
%%

然后是我的野牛(我没有实现 COS SIN 和其他最容易阅读的东西):

 %defines
%{
#include <iostream>
#include <math.h>
using namespace std;
extern int yylex();
extern void yyerror(char const* msg);
%}

%union {double num;}

/* CARACTERES */
%token <num> NUMBER PI
%token OP CP SEP END

/* TRIGO */
%token COS SIN TAN
%token ACOS ASIN ATAN
/* CALCUL */
%token ADD SUB
%token MUL DIV
%token ROOT POW MODULO EXP ABS

/* CALCUL ORDER */
%left ADD SUB
%left MUL DIV

/* TRASH */
%token ERROR

%type <num> calclist exp factor term
%start calclist
%%
calclist: /* nothing */
 | calclist exp END {cout << $2 << endl;}
 ;
exp: factor
 | exp ADD factor { $$ = $1 + $3; }
 | exp SUB factor { $$ = $1 - $3; }
 ;
factor: term
 | factor MUL term { $$ = $1 * $3; }
 | factor DIV term { $$ = $1 / $3; }
 ;
term: NUMBER
 | OP exp CP {$$ = $2;}
 ;
%%



extern void yyerror(char const* msg){
  cerr << "Error " << msg << endl;
}

然后是我的主要:

#include <iostream>
#include "parser.hpp"
#include <string.h>
using namespace std;

extern FILE *yyin;
extern int yy_scan_string(const char *);


int main(int argc, char const *argv[]) {
  /*string buf(argv[1]);
  buf.append("\0");*/
  yy_scan_string(argv[1]);
  return yyparse();
}

最后是我的makefile:

all: bison flex main.cpp
    g++ parser.cpp lexer.cpp main.cpp -o parser
    rm lexer.cpp parser.cpp parser.hpp
    ./parser "(1+2)"
bison: parser.y
    bison -o parser.cpp parser.y
flex: lexer.l
    flex -o lexer.cpp lexer.l

我也试过./parser (1+2),但我得到了更多错误。 感谢您的帮助!

【问题讨论】:

    标签: c++ bison lex argv


    【解决方案1】:

    来自Flex & Bison book(第124页):

    yy_scan_bytes 和yy_scan_string 例程创建一个缓冲区,其中包含要扫描的文本副本。

    (强调我的)

    和

    创建字符串缓冲区后,使用yy_switch_to_buffer 告诉扫描器从中读取...

    yy_scan_string 仅创建您需要显式使用的缓冲区对象:

    YY_BUFFER_STATE bp = yy_scan_string(...);  // Creates a buffer from the string
    yy_switch_to_buffer(bp);                   // Use the buffer
    int ret = yyparse();                       // Parse the string
    yy_delete_buffer(bp);                      // Free the buffer
    

    【讨论】:

    • 非常感谢!我需要为 YY_BUFFER_STATE 添加一些东西吗?我得到了一个错误,也切换到缓冲区!
    • @G.Courmont 我不记得了,很久以前我自己使用过 Flex/Bison。我现在基本上只是阅读链接的书,并且在我阅读的部分中没有说任何内容。您必须搜索自动生成的头文件,以及您系统上安装的与 Flex/Bison 相关的其他头文件。
    • 这个答案不正确。请参阅 flex 文档。
    【解决方案2】:

    我终于找到了答案。 我只是不得不改变一点我的主要:

    string str = argv[1];
    str += '\n';
    yy_scan_string(str.c_str());
    

    因为 yyin 是 0-Terminated。 希望这对其他人有所帮助!

    【讨论】:

      猜你喜欢
      • 2015-10-28
      • 2014-03-20
      • 2017-02-10
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 2010-11-12
      • 1970-01-01
      相关资源
      最近更新 更多