Lark : 如何只挑选一些图案

问题描述

我只想从文本文件提取一些结构化模式。

例如,在下面的文本中:

   blablabla 
   foo FUNC1 ; blabliblo blu

我只想隔离'foo FUNC1 ;'。

我试图将 lark 解析器与以下解析器一起使用

foo=Lark('''
  start:  statement*
  statement: foo 
           | anything
  anything : /.+/
  foo : "foo" ID ";"
  ID : /_?[a-z][_a-z0-9]*/i
  %import common.WS
  %import common.NEWLINE
  %ignore WS
  %ignore NEWLINE
''',parser="lalr",propagate_positions=True)

但是标记“anything”可以捕获所有内容。有没有办法让它不贪婪?以便标记 'foo' 可以捕获给定的模式?

解决方法

你可以通过优先级来解决这个问题。

对于parser="lalr",Lark 支持终端优先级。因此,您可以将 "foo" 移动到它自己的终端中,然后为该终端分配比 anything 终端(默认优先级为 1)更高的优先级:

  foo : FOO ID ";"
  FOO.2: "foo"

解析您的示例字符串然后结果:

start
  statement
    anything    blablabla 
  statement
    foo
      foo
      FUNC1
  statement
    anything    blabliblo blu

对于 parser="earley",Lark 支持规则的优先级,因此您可以使用:

  foo.2 : "foo" ID ";"

解析您的示例字符串然后结果:

start
  statement
    anything    blablabla 
  statement
    foo FUNC1
  statement
    anything     blabliblo blu