使用正则表达式库在 C++ 中创建词法分析器?

Posted

技术标签:

【中文标题】使用正则表达式库在 C++ 中创建词法分析器?【英文标题】:Using regex library to create lexical analyzer in C++? 【发布时间】:2017-02-20 17:12:51 【问题描述】:

我正在尝试用 C++ 编写一个 XML 扫描器。理想情况下,我希望使用正则表达式库,因为它会更容易。

但是,我有点不知道该怎么做。因此,首先我需要为语言中的每个标记创建正则表达式。除了令牌的名称之外,我还可以使用映射来存储这些正则表达式对。

接下来,我将打开一个输入文件,并希望使用迭代器来遍历文件中的字符串并将它们与正则表达式匹配。但是,在 XML 中,您没有空格来分隔字符串。

所以我的问题是这种方法是否有效?此外,正则表达式库究竟将如何满足我的需求? regex_match 是否足以以万无一失的方式满足我的需求,以免我的扫描仪被欺骗?

我只是想在我的脑海中创建一个流程的骨架,以便我可以开始处理这个问题。我想从其他人那里得到一些意见,看看我是否正确地考虑了这个问题。

如果您对此有任何想法,我将不胜感激。非常感谢!

【问题讨论】:

为什么要重新发明***? lex/flex 已经存在了几十年,并且已经解决了所有问题。 我正在学习如何进行词法分析。仅仅为我生成代码并没有太大帮助。 我同意这些工具很有用,但我想自己学习如何做。 好吧,也许你应该自己写一个正则表达式求值器,然后呢?即使是那个正则表达式库也可以为你工作。 是的。但是看看那些其他工具,它的可读性要低得多,而我对正则表达式的理解就在于构建它们。我可以手动扫描,但我也读过另一个选择是使用正则表达式。 【参考方案1】:

词法分析通常通过顺序匹配标记来进行,其中每个标记对应于一组可能的正则表达式中最长的匹配。由于每个匹配都锚定在前一个标记结束的位置,因此不执行搜索。

在这里,我稍微宽松地使用了“token”这个词; whitespace 和 cmets 也作为标记匹配,但在大多数编程语言中,它们在被识别后会被简单地忽略。不过,符合标准的 XML 标记器需要将它们识别为标记,因此对于您的问题域而言,用法将是精确的。

您可能想了解 (f)lex,而不是让自己沉浸在烦人的细节中,它可以在给定正则表达式集合的情况下有效地实现该算法。它还负责缓冲区处理和其他一些细节,让您可以专注于理解词法分析过程的性质。

【讨论】:

【参考方案2】:

有一个工具,称为 RE/flex 可以生成扫描仪:

https://sourceforge.net/projects/re-flex

生成的扫描器使用 Boost.Regex 等正则表达式引擎。 Boost.Regex 通过 API 用于处理不同类型的输入,因此有一些额外的 C++ 代码。不是您可能正在寻找的最简单的 Boost.Regex API 调用。

RE/flex 中包含的示例包括一个 C++ 中的 XML 扫描器,可以帮助您入门。 RE/flex 还支持 UTF-8 编码,您需要正确扫描 XML。

【讨论】:

以上是关于使用正则表达式库在 C++ 中创建词法分析器?的主要内容,如果未能解决你的问题,请参考以下文章

实现词法分析器时的 DFA 与正则表达式?

python 简单的基于正则表达式的词法分析器

编译原理词法分析

编译原理词法分析

自制Lex-词法分析器生成器(C++)

编译原理-第三章 词法分析-3.7 从正则表达式到自动机-从正则表达式构造NFA