我正在为linux命令创建一个repl。

问题描述 投票:0回答:1

您可以使用

transformer

,并具有

%ignore WS
代币返回的方法。

转换器使将解析的结果转换为其余程序所需的格式变得更加容易。 由于您没有包括语法,并且特定用例太复杂而无法快速复制,我将使用以下基本语法展示一个示例:

WS

在定义变压器之前,我们可以看到所有int和空间都存在于解析的树上:
python parsing read-eval-print-loop lark-parser
1个回答
2
投票
Discard

我们可以定义一个仅转换GRAMMAR = r""" ?start: ints ints: (INT WS*)+ %import common (INT, WS) """

的简单变压器 >>> Lark(GRAMMAR).parse('12 34 56') Tree(Token('RULE', 'ints'), [Token('INT', '12'), Token('WS', ' '), Token('INT', '34'), Token('WS', ' '), Token('INT', '56')])
它们与以前相同的树,但现在已删除了
WS

代币:

from lark import Lark, Token, Transformer, Discard class SpaceTransformer(Transformer): def WS(self, tok: Token): return Discard

可以进一步扩展变压器以处理更多定义的令牌:

WS

导致值是正确的整数,但它们仍在树上:

>>> tree = Lark(GRAMMAR).parse('12 34 56')

>>> SpaceTransformer().transform(tree)
Tree(Token('RULE', 'ints'), [Token('INT', '12'), Token('INT', '34'), Token('INT', '56')])

我们也可以将其更进一步,并定义一个规则的方法 - 对于每个匹配的解析值,将自动调用与令牌或规则匹配的变压器中的每种方法:

class SpaceTransformer(Transformer):
    def WS(self, tok: Token):
        return Discard

    def INT(self, tok: Token) -> int:
        return int(tok.value)

现在,当我们改变树时,我们会得到一个int的列表,而不是树:
>>> tree = Lark(GRAMMAR).parse('12 34 56')

>>> SpaceTransformer().transform(tree)
Tree(Token('RULE', 'ints'), [12, 34, 56])

尽管我的示例使用了非常简单的类型,但您可以为返回

class SpaceTransformer(Transformer): def WS(self, tok: Token): return Discard def INT(self, tok: Token) -> int: return int(tok.value) def ints(self, integers): return integers
对象的规则定义一种方法,或者您定义的任何代表它的方法。  对于包含其他规则的规则,外部规则将接收已转换的对象,就像
>>> tree = Lark(GRAMMAR).parse('12 34 56') >>> SpaceTransformer().transform(tree) [12, 34, 56]

接收到的int对象一样。

也有一些自定义可以应用于变压器方法通过使用
command

装饰器接收参数的方式。

对于没有大量空格的语言(我相信像Bash一样的语言资格)应该足以添加:

Command
并从语法上删除所有其他白色空间处理。例如:

ints
将变得简单:
v_args

在像该空格这样的语法中,将其视为令牌之间的边界,但在语法定义或结果的解析树中不必进一步处理。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.