【问题标题】:Bison/Flex Parsing FileBison/Flex 解析文件
【发布时间】:2013-09-29 14:06:31
【问题描述】:

我最近尝试使用GNU BisonFlex 编写解释器。我希望解释器识别的文本是print "Hello",我尝试了以下方法:

flex file:

%{
#include <iostream>
using namespace std;
#define YY_DECL extern "C" int yylex()
#include "gbison.tab.h"
%}
%%
[ \t\n]            ;
'\"'               return QUOTE;
[a-zA-Z0-9]+       { yylval.sval = strdup(yytext); return STRING; }
%%

bison file:

%{
#include <cstdio> 
#include <cstring>
#include <iostream>
using namespace std;

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

void yyerror (const char* s);
%}

%union {
  char* sval;
}

%token <sval> STRING
%token QUOTE
%%

str:
    STRING QUOTE STRING QUOTE
    {
       if (strcmp($1, "print") == 0)
       {
           cout << $3 << flush;
       }
       if (strcmp($1, "println") == 0)
       {
           cout << $3 << endl; 
       }
    }
    ;
%%

main(int argc, char* argv[])
{
   FILE* input = fopen(argv[1], "r");
   if (!input)
   {
      cout << "Bad input. Nonexistant file" << endl; 
      return -1;
   } 

   yyin = input;

   do 
   {
       yyparse();
   } while (!feof(yyin));

}
void yyerror(const char* s)
{
   cout << "Error. " << s << endl; 
   exit(-1);   
}

但是当我将print "hello" 传递给已编译的程序时,我得到: "Error. syntax error

我认为问题出在STRING QUOTE STRING QUOTE,但我不确定。到底出了什么问题?如何让解释器打印hello

【问题讨论】:

    标签: interpreter bison flex-lexer


    【解决方案1】:

    答案如下,但我希望以下内容更普遍,作为钓鱼指导。

    有多种调试工具可以帮助您。特别是,flex 提供了-d 标志:

    -d, --debug

    使生成的扫描仪在“调试”模式下运行。每当识别出一个模式并且全局变量yy_flex_debug 不为零(这是默认值)时,扫描器就会向stderr 写入一行……(flex manual

    bison 还提供调试工具。 (bison manual)

    有几种方法可以启用跟踪工具的编译:
    • YYDEBUG
    • 选项-t(符合POSIX Yacc)...
    • 选项--debug(Bison 扩展)...
    • 指令%debug
    我们建议您始终启用调试选项,以便调试 总是可能的。

    使用跟踪工具编译程序后, 请求跟踪是在变量yydebug 中存储一个非零值。 您可以通过让 C 代码执行此操作(可能在 main 中),或者您 可以使用 C 调试器更改值。

    另外,请记住 flex 会插入一个自动规则,该规则会导致将任何其他无法识别的字符回显到输出中。 (“默认情况下,任何与 flex 扫描仪不匹配的文本都会被复制到输出中”--Some simple examples)这就是为什么您的程序正在打印的错误消息中有额外的"

    "Error. syntax error
    ^
    

    不过,这有点微妙。追踪flex 会更直接地向您展示这一点。

    所以,最后,问题是:

    1. 弹性模式'\"' 不匹配 "。它匹配 '"',因为单引号对于 flex 不是特别的。这绝对是您解析失败的原因。

    2. 修复这将使您的程序解析单个命令,但如果您尝试在同一输入中为其提供两个打印命令,则会产生语法错误。这是因为野牛总是解析直到它从词法分析器接收到END 标记,并且词法分析器(默认情况下)仅在到达输入末尾时提供END 标记。你可以改变

      • 词法分析器行为(通过在其他情况下发送END,例如换行符)(推荐)

      • 解析器行为(通过使用ACCEPT)(可能,但很少需要)

      • 语法,因此它可以识别任意数量的语句。 (推荐

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多