【问题标题】:Should a Lexer be able to distinguish between Syntax Tokens contained in a "variable" and actual Syntax TokensLexer 是否应该能够区分“变量”中包含的语法标记和实际的语法标记
【发布时间】:2021-01-25 02:45:49
【问题描述】:

我正在为一种简单的语言(小黄瓜)编写词法分析器。

虽然一些词法分析器已经完成,但我正在为设计决策而苦苦挣扎。

目前,词法分析器具有示例和步进模式。 这意味着它必须跟踪上下文,我宁愿不这样做。 我想让词法分析器尽可能地笨,以便大部分工作由解析器完成。

我对当前方法的问题是我不知道在某些情况下词法分析器是否应该区分语法和文字。

为了更好地理解,这里是该语言的简要概述。

  • 该语言具有如下语法标记:: < > | @

  • 语言可以有变量,写成<Name>

  • 该语言有一个示例部分,其中语法标记与测试用例的其余部分不同

示例表如下所示:

Examples:
| Name | Last Name |
| John | Doe |

用 Gherkin 编写的完整(去除不需要的信息)测试如下所示:

@Fancy-Test
    Scenario Outline: User logs in 
    
    Given user is on login_view
    And user enters <Username> in username_field
    And user enters <Password> in password_field
    And user answers <Qu|estion>
    When user clicks on login_button
    Then user is logged in
    
    Examples:
    |Username|Password|Qu\|estion|
    |JohnDoe11|Test<Pass>@@Word|Who am I|

请注意我是如何在第一个示例列中转义 | 的。

还要注意密码示例中的所有语法字符。

通过转义 | 字符,我可以在测试的示例部分中使用它,而不会被检测为语法标记。

但是对于And user answers &lt;Qu|estion&gt; 行中的变量,我不需要也不想转义它。 根据语言规范,示例条目可以包含除 | 之外的任何字符,除非转义,因为它标志着列的结尾。

这意味着不应将其他语法字符检测为语法标记。 如果没有两种模式,密码示例中的所有语法字符都将被检测为此类令牌。

其他部分的测试情况正好相反。 除非在新行的开头(其中@: 是语法标记), 只有&lt;&gt; 应该被视为语法的一部分

当前的实现通过提到两种模式来防止这种情况,这不是最好的解决方案。

因此,我的问题是: 词法分析器是否应该将其检测为语法标记,然后被解析器拾取,从而确定这些是文字的实际部分? 或者有上下文是更可取的方式。

感谢您的回答。

【问题讨论】:

  • 让解析器处理转义序列之类的事情会变得非常复杂。在词法分析器中处理它会给词法分析器增加一些复杂性,但不像解析器那样几乎是AD。
  • 这就是为什么我在词法分析器的任务中添加了转义字符。但问题仍然是我不确定,如果词法分析器应该关心它是在示例列表中,还是在测试定义的其他部分中。因为两者的语法标记不同。
  • 对于这样的事情,我个人可能会使用两种不同的词法分析器和解析器。主要部分各一份,示例部分各一份。这是因为两个部分之间的规则似乎如此不同。但是可以共享很多代码,尤其是对于词法分析器。
  • 所以这基本上是我的第一次尝试,只是更清楚地表明它实际上是两种不同的情况,而不是快速模式切换。

标签: parsing grammar lexer


【解决方案1】:

如果你有两个不同的词法环境,那么你就有两个不同的词法环境。他们需要以不同的方式处理。几乎所有现实世界的编程语言都具有这种复杂性,并且大多数词法生成器都具有旨在帮助维持适度的词法状态的机制。

问题在于如何在不同的词汇上下文之间进行转换。正如您所注意到的,这可能需要大量工作,这很丑陋。如果它真的很难看,您可能需要重新审视您的语言设计,因为不仅您的解析器必须能够预测哪个词汇上下文适用于何处:任何阅读代码的人也需要理解这一点,并且所有算法内置的微妙之处。如果你不能用几句话来描述算法,你会给代码阅读者带来很大的负担。

在 Gherkin 的情况下,在我看来,这些表格很容易识别:它们从第一个标记为 | 的行开始,大概会一直持续到第一个标记不是 @987654322 的行@。因此,切换词法上下文应该非常简单,尤其是当您的词法分析器可能已经需要注意行尾时。

【讨论】:

  • 感谢您的出色回答。我不确定切换上下文是否是词法分析器应该做的事情。这基本上总结了我的想法。只是一个简单的提示,但不会改变您的答案:示例总是以示例开头:
  • @broken-bytes:我明白了,但我简要查看的文档还有数据表语法的其他用途,没有用 Examples: 关键字介绍,我想你可能正在寻找一个更通用的解决方案(通常是一个好主意)。无论如何,我是否理解你的语言并不重要:-)
  • 不,你说得对。只是想说明这一点,以防万一会改变任何事情。但是你是对的,数据表可以有不同的使用方式,尽管它们通常不在同一个文件中。
猜你喜欢
  • 2021-06-03
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多