【问题标题】:Lex and YACC (FLEX and Bison)Lex 和 YACC(FLEX 和 Bison)
【发布时间】:2021-12-03 09:55:48
【问题描述】:

您好,我需要了解 flex 和 bison 才能重写为 QRegExp,出现以下问题。 如果代币同时适用于多个团队,那么 YACC / BISON 将如何行动? 例如,有一个 FLOAT_NUM 令牌, 有两个命令:

  • 第一个需要两个令牌(STARTED 和 FLOAT_NUM)

     title: STARTED FLOAT_NUM
        {
         .
         .
         .
        }
    
  • 第二条命令只需要 FLOAT_NUM 令牌

      my_type: FLOAT_NUM
         {
          .
          .
          .
         }
    

相应地,YACC/Bison 的表达式如下:

STARTED FLOAT_NUM

我是否正确理解只有“title”命令才有效,而“my_type”命令只有在一个 FLOAT_NUM 到达时才有效,而其他什么都没有?

【问题讨论】:

  • LR 解析严格从左到右;它不会在输入中搜索。但是完整的解释需要教科书中的一章,这对于 SO 答案的期望太高了。问一个关于你实际在做什么的具体问题会好得多,这可以在这里回答。

标签: bison yacc


【解决方案1】:

Yacc 会生成一个state machine,该state machine 一次接受一个令牌,并根据当前状态和令牌决定下一个状态。

例如,在您的情况下,如果它获得令牌 STARTED,它可能会进入一种状态,可以描述为“我在终端 title 的位置 1 并且我期望令牌 FLOAT_NUM现在”。 要回答如果令牌X 到达会发生什么的问题,您始终需要首先知道解析器当前处于哪个状态。

很难使用不完整的示例,因此我假设您的完整程序如下所示:

%token STARTED FLOAT_NUM

%start main

%%

main: title | my_type {}
title: STARTED FLOAT_NUM {}
my_type: FLOAT_NUM {}

解析从起始终端的开头开始(在本例中为main),并在到达起始终端的末尾时结束。

因此,在这种情况下,开始终端可以由titlemy_type 组成,因此解析器期望第一个标记是STARTEDFLOAT_NUM。 当它得到其中任何一个时,解析器可以明确地知道它当前是在title 还是my_type。如果示例不同并且它们以相同的标记开始,则解析器将进入状态“titlemy_type,现在给我第二个标记”,然后解析将继续。

您可以通过运行bison 和选项-r all 来查看所有生成的状态是什么以及它们如何相互变化,该选项会创建一个人类可读的文件,其中包含生成的状态机的完整报告。

这是完整的基础知识。我希望它有所帮助。

如果这还不够,我建议阅读bison manual,尤其是section describing the state machine

【讨论】:

    猜你喜欢
    • 2010-11-28
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多