【问题标题】:Lexer and parser in C++ from EBNF来自 EBNF 的 C++ 中的词法分析器和解析器
【发布时间】:2014-04-17 09:32:10
【问题描述】:

我需要为给定的语法编写一个词法分析器和一个解析器(我需要手工制作而不是使用生成器)。我做了很多研究,但我仍然不知道如何编码。

例如我有(EBNF 中的语法):

<Letter> ::= [A-Za-z]

<IntegerLiteral> ::=<Digit> { <Digit> }

这需要在词法分析器或解析器中定义吗?怎么做?

我知道词法分析器应该逐个字符地读取文件并输出标记,然后将这些标记传递给解析器以创建解析树,但是我陷入了编码中。

【问题讨论】:

  • “我需要手工制作而不是使用发电机”:这是否会阻止您使用 boost spirit? (www.boost.org)。
  • '它是一个生成器吗?' 除了需要使用 c++ 编译器之外的任何东西。
  • 如果你对这个话题感兴趣,看看其他编译器手工制作他们的东西,我想 Clang 的 Lexer 类是很好的灵感来源。
  • 查看我关于如何编写递归下降解析器的 SO 答案,使用 EBNF 作为直接指导告诉您编码的内容:stackoverflow.com/questions/2245962/…

标签: c++ parsing compiler-construction lexical-analysis


【解决方案1】:

您向我们展示的内容看起来像是定义了令牌类型。所以它进入了词法分析器。

编写词法分析器的诀窍是简单地获取输入文本(只是一长串单个字符)并逐个查看它们。每次查看一个字符时,根据上面的 EBNF 对其进行分类(即它是 Letter 还是 IntegerLiteral),然后生成适当的标记。

现在您上面的语法听起来毫无意义(它会生成单个字符和单个数字标记)所以我的猜测是您有更多类似这样的规则,它们使用这些规则使定义更具可读性。所以实施那些更复杂的规则。编写一个函数来检测一个字符是否匹配其中一个子规则。

当你发现当前字符与前一个字符的类型不匹配时,完成当前字符并开始一个新字符。

这就是它的全部内容。你只需要一堆布尔值来跟踪类型。

【讨论】:

  • 是否有网站演示如何做到这一点?为什么要使用布尔值来跟踪类型?回答是的,我确实有更复杂的规则,我只写了两个简单的规则。另外,如何将字符分类为上述 EBNF?
  • 因为布尔值是用来记住打开或关闭的东西的最简单的类型(即我是在一个整数或双精度数中,我是在一个整数中但只是遇到了一个句点,所以它现在只能是小数等)。你也可以将它实现为一个成熟的状态机,但每当我提到“状态机”这个词时,人们都会感到害怕,所以我想我应该把它排除在解释之外。
猜你喜欢
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 2011-04-07
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-03
相关资源
最近更新 更多