
本文旨在解决 TatSu 语法解析器中方括号被意外忽略的问题。通过分析问题代码,指出 @@whitespace 指令的错误使用是导致该问题的根本原因,并提供修改方案,即将 @@whitespace 指令设置为 None 或 False 来禁用空格处理,从而确保方括号能被正确解析。
在使用 TatSu 构建语法解析器时,有时会遇到某些字符被意外忽略的情况,例如方括号 []。这通常不是 TatSu 的 bug,而是由于对语法定义的某些细节理解不正确导致的。本文将以方括号被忽略为例,详细分析问题原因,并提供解决方案。
问题分析
问题的核心在于 @@whitespace 指令。虽然文档中可能存在歧义,但实际上 @@whitespace 指令定义的是需要跳过的字符列表,而不是定义空格的处理方式。因此,当我们将 @@whitespace 设置为包含方括号的字符集时,TatSu 会在解析过程中主动跳过这些字符,导致它们被忽略。
解决方案
要解决方括号被忽略的问题,最直接的方法是禁用空格处理。可以通过将 @@whitespace 指令设置为 None 或 False 来实现。
修改后的 TatSu 语法定义如下:
@@grammar::Markdown
@@whitespace :: None # 或者 @@whitespace :: False
start = pieces $ ;
text = text:/[a-z]+/ ;
pieces = {text}*
;代码示例
以下是一个完整的代码示例,展示了如何禁用空格处理并正确解析包含方括号的字符串:
import tatsu
grammar = """
@@grammar::Markdown
@@whitespace :: None
start = pieces $ ;
text = text:/[a-z]+/ ;
pieces = {text}*
;
"""
class MarkdownSemantics:
def pieces(self, ast):
return ''.join(ast)
parser = tatsu.compile(grammar)
markdown_str = "[]"
ast = parser.parse(markdown_str, semantics=MarkdownSemantics())
print(ast)运行此代码,将不再出现方括号被忽略的问题,而是能够正确解析包含方括号的字符串。
注意事项
- 在禁用空格处理后,所有字符都将被视为有效字符,包括空格、制表符等。因此,需要确保语法定义能够正确处理这些字符。
- 如果只需要处理特定的空格字符,可以自定义 @@whitespace 指令,仅包含需要跳过的字符。
总结
通过理解 @@whitespace 指令的真正含义,并正确设置其值,可以有效解决 TatSu 语法解析器中字符被忽略的问题。在编写 TatSu 语法定义时,务必仔细阅读文档,并进行充分的测试,以确保语法解析器的行为符合预期。










