- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 Lark 为 BASIC 创建一个 LALR 解析器,而且我很难解决“END”语句和“END IF”等语句之间的冲突。这是语法的简化版本:
%ignore /[ \t\f]+/
program: _nlopt _part_list
_part_list: (stmt | block) _nl _part_list
|
_nlopt: _nl
|
_nl: _NEWLINE _nl
| _NEWLINE
block: if_block
stmt: print_stmt
| end_stmt
end_stmt: END_KW
if_block: IF_KW expr THEN_KW _nl block_body endif_stmt
endif_stmt: END_KW IF_KW
block_body: _block_body_item block_body
|
_block_body_item: stmt _nl
print_stmt: PRINT_KW expr
?expr: NUMERIC_LITERAL
_NEWLINE: "\n"
NUMERIC_LITERAL: /[\-+]?\d+(\.\d*)?[!#%&]?/
END_KW: "end"i
IF_KW: "if"i
PRINT_KW: "print"i
THEN_KW: "then"i
如果我用这样的代码尝试这个语法:
parser = Lark(grammar, start='program', parser='lalr')
prog = r"""
if 1 then
print 200
end if
"""
t = parser.parse(prog)
print(t.pretty())
这是我从 Lark 得到的:
Traceback (most recent call last):
File "test.py", line 230, in <module>
t = parser.parse(prog)
File "/home/user/.pyenv/versions/venv/lib/python3.6/site-packages/lark/lark.py", line 250, in parse
return self.parser.parse(text)
File "/home/user/.pyenv/versions/venv/lib/python3.6/site-packages/lark/parser_frontends.py", line 37, in parse
return self.parser.parse(token_stream, *[sps] if sps is not NotImplemented else [])
File "/home/user/.pyenv/versions/venv/lib/python3.6/site-packages/lark/parsers/lalr_parser.py", line 68, in parse
for token in stream:
File "/home/user/.pyenv/versions/venv/lib/python3.6/site-packages/lark/lexer.py", line 341, in lex
for x in l.lex(stream, self.root_lexer.newline_types, self.root_lexer.ignore_types):
File "/home/user/.pyenv/versions/venv/lib/python3.6/site-packages/lark/lexer.py", line 175, in lex
raise UnexpectedCharacters(stream, line_ctr.char_pos, line_ctr.line, line_ctr.column, allowed=allowed, state=self.state)
lark.exceptions.UnexpectedCharacters: No terminal defined for 'i' at line 4 col 5
end if
^
Expecting: ['__IGNORE_0', '_NEWLINE']
如果我删除“end_stmt”规则,就不会发生这种情况。有没有办法修复语法以防止这种情况发生?
最佳答案
默认情况下,Lark 不会警告您语法中的 shift-reduce 冲突,而是默默地解决它们以支持 shifting。这通常会导致解析器无法解析您想要的内容——就像这里的情况一样。你可以通过传递 debug = True
来让 lark 警告你这些冲突。标记为 Lark()
.这样,您甚至可以在通过测试发现问题之前就发现问题所在,甚至可以获得有关问题所在的有用信息。
随着 debug
选项已启用,您将收到一条警告,指出存在 shift-reduce 冲突,其中 END_KW
可能意味着当前 block_body
结束了或者可能是end_stmt
.这是一个问题,因为 LALR(1) 解析器只能向前看一个标记,但我们必须向前看第二个标记以查看是否有 if
。在end
之后正确决定采取哪个选项。
您可以通过转动 end if
来解决这个问题,有点笨拙。变成这样的单个标记:
ENDIF_KW: /end[ \t\f]+if/i
然后使用 ENDIF_KW
而不是 END_KW IF_KW
.
PS:请注意,如果您使用 Earley 解析而不是 LALR(1),您的语法在没有这些更改的情况下也能正常工作。
关于python - BASIC语法中 "END"和 "END IF"之间的冲突,使用Lark,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56079928/
我一直在试验 lark ,但遇到了一个小问题。假设我有以下语法。 parser = Lark(''' ?start: value | start "or" value
我正在尝试编写一个 SMTP 解析器,并从 rfc 中获取一些引用字符串的信息。 .所以我有以下语法(取出所有有效的部分,关注无效的部分): quoted_string : /[\x22]/ qco
我的语法有一个优先级问题,我没有更多的想法来解决它。 我正在使用 Lark 事情是这样的(我已经尽可能地简化了问题): from lark import Lark parser = Lark(r"""
我正在尝试解析我正在编写的一些伪代码,但在获取符号值时遇到了一些问题。它解析成功,但不会返回与“常规”字符相同的值。这是一个例子: >>> from lark import Lark >>> pars
我正在为 rules_scala 实现类似 Strict Java Deps 的功能。 如果使用 warn 或 error,我真的很想能够在运行时进行配置。 我似乎记得 skylark 规则无法创建和
让我们首先考虑使用 lark 的简单 json 解析器: import sys from lark import Lark, Transformer, v_args json_grammar = r"
假设我有以下内容: items : (item separator)+ 这适用于: i1, i2, i3, 但不适用于: i1, i2, i3 如何做到不需要结尾分隔符? 最佳答案 这看起来更像是您需
我正在使用 lark,一个优秀的 python parsing library . 它提供了 Earley 和 LALR(1) 解析器,并通过 custom EBNF format 定义。 . (EB
如何实现可以导入文件并仍然使用 LARK 解析它的语法? 例如: @import file.txt ..... 最佳答案 我找到了一个看起来相关的 GitHub,这就是您要找的吗? https://g
考虑 Python Lark parser 的这个简单测试: GRAMMAR = ''' start: container* container: string ":" "{" (container
我正在尝试使用 lark 实现记录定义 DSL .它基于缩进,这让事情变得有点复杂。 Lark 是一个很棒的工具,但我遇到了一些困难。 这是我正在实现的 DSL 的一个片段: record Order
Lark 解析器预定义了一些常见的终端,包括一个字符串。它的定义如下: _STRING_INNER: /.*?/ _STRING_ESC_INNER: _STRING_INNER /(?
我正在尝试为 dsl 编写 lark 语法,但在使用此字符串插值语法时遇到了问题: " abc " <- normal string " xyz~{expression}abc " <- string
我在运行 checkov 时遇到一些问题,我不熟悉 python 库,任何人都可以给我一些提示吗? 这在某些机器上运行良好,但在这台机器上尤其不行...... 在 CentOS 中运行: $ chec
我已经编写了cs143 course中指定的decaf语法. 这是我的代码。 import sys from lark import Lark, Transformer, v_args decaf_g
我是一名优秀的程序员,十分优秀!