【发布时间】: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 <Qu|estion> 行中的变量,我不需要也不想转义它。
根据语言规范,示例条目可以包含除 | 之外的任何字符,除非转义,因为它标志着列的结尾。
这意味着不应将其他语法字符检测为语法标记。 如果没有两种模式,密码示例中的所有语法字符都将被检测为此类令牌。
其他部分的测试情况正好相反。
除非在新行的开头(其中@ 和: 是语法标记),
只有<> 应该被视为语法的一部分
当前的实现通过提到两种模式来防止这种情况,这不是最好的解决方案。
因此,我的问题是: 词法分析器是否应该将其检测为语法标记,然后被解析器拾取,从而确定这些是文字的实际部分? 或者有上下文是更可取的方式。
感谢您的回答。
【问题讨论】:
-
让解析器处理转义序列之类的事情会变得非常复杂。在词法分析器中处理它会给词法分析器增加一些复杂性,但不像解析器那样几乎是AD。
-
这就是为什么我在词法分析器的任务中添加了转义字符。但问题仍然是我不确定,如果词法分析器应该关心它是在示例列表中,还是在测试定义的其他部分中。因为两者的语法标记不同。
-
对于这样的事情,我个人可能会使用两种不同的词法分析器和解析器。主要部分各一份,示例部分各一份。这是因为两个部分之间的规则似乎如此不同。但是可以共享很多代码,尤其是对于词法分析器。
-
所以这基本上是我的第一次尝试,只是更清楚地表明它实际上是两种不同的情况,而不是快速模式切换。