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