所以我正在学习 Lepl 教程,一个 Python 解析器,但我无法弄清楚 likeToken(Real())
和 just之间到底有什么区别Real()
。我找到了有关该功能的文档,但它们非常无用。
那么,Token() 类究竟做了什么?为什么它与常规 Lepl 课程不同?
所以我正在学习 Lepl 教程,一个 Python 解析器,但我无法弄清楚 likeToken(Real())
和 just之间到底有什么区别Real()
。我找到了有关该功能的文档,但它们非常无用。
那么,Token() 类究竟做了什么?为什么它与常规 Lepl 课程不同?
通常,LEPL 对输入中的字符流进行操作。这很简单,但正如您所见,您需要大量冗余规则来忽略例如空格,只要它合法但被忽略。
这个问题有一个常见的解决方案,即首先通过一个相对简单的自动机运行输入字符串,该自动机负责处理这个问题和其他干扰。它将输入分成几部分(例如数字、标识符、运算符等)并去除被忽略的部分(例如注释和空格)。这使得解析器的其余部分更简单,但是 LEPL 的默认模型没有这个自动机的位置,顺便说一下,它被称为标记器或词法分析器(简称 lexer)。
每种标记通常被定义为一个正则表达式,用于描述每个标记的内容,例如[+-][0-9]+
整数。您可以(有时应该)使用 来做到这一点Token()
,例如,Token('a+b+')
提供一个解析器,它消耗与正则表达式匹配的输入一样多的输入,然后将其作为单个字符串返回。在大多数情况下,这些解析器和其他所有解析器一样工作,最重要的是,它们可以以相同的方式组合。例如,Token('a+') & Token('b+')
除了产生两个字符串之外,它的工作原理和前一个等效,并且Token('a+') + Token('b+')
完全等效。到目前为止,它们只是一些语法的一些基本构建块的较短符号。你也可以使用一些LEPL 的类Token()
将其转换为等效的正则表达式并将其用作标记 - 例如Token(Literal('ab+'))
is Token(r'ab\+')
。
一个重要的区别和巨大的优势是,使用标记,如果没有其他标记可以匹配,您还可以提供插入并丢弃一些输入的模式 - 默认丢弃空格,这使得忽略空格非常容易(同时仍然允许解析器在某些地方需要空格)。缺点是您必须将所有非令牌匹配器包装在令牌中,或者如果无法自动转换它们,则必须手动编写等效规则。