您可以使用
transformer,并具有
%ignore WS
代币返回的方法。
转换器使将解析的结果转换为其余程序所需的格式变得更加容易。 由于您没有包括语法,并且特定用例太复杂而无法快速复制,我将使用以下基本语法展示一个示例:
WS
在定义变压器之前,我们可以看到所有int和空间都存在于解析的树上: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
在像该空格这样的语法中,将其视为令牌之间的边界,但在语法定义或结果的解析树中不必进一步处理。