我正在尝试使用类似于 Treetop 的 Citrus for Ruby 中的语法来处理最终将成为布尔逻辑的内容。我遇到了递归问题,但我不清楚具体原因。这是我要处理的文本(最后应该有一个换行符):
COMMANDWORD # MYCOMMENT
这是我的 Citrus 语法(旨在处理更高级的东西):
grammar Grammar
rule commandset
command+
end
rule command
identifier command_detail* comment_to_eol* "\n"
end
rule command_detail
assign_expr | expr
end
rule assign_expr
identifier ":=" expr
end
rule expr
# Stack overflow
or_expr | gtor_expr
# No problem!
# or_expr
end
rule or_expr
# Temporarily match everything except a comment...
[^#]+
# What I think will be correct in the future...
# gtor_expr "OR" expr
end
rule gtor_expr
and_expr | gtand_expr
end
rule and_expr
gtand_expr "AND" gtor_expr
end
rule gtand_expr
not_expr | gtnot_expr
end
rule not_expr
"NOT" gtnot_expr | gtand_expr
end
rule gtnot_expr
parens_expr | identifier
end
rule parens_expr
"(" expr ")"
end
rule identifier
ws* [a-zA-Z0-9]+ ws*
end
rule ws
[ ]
end
rule comment_to_eol
"#" [^\n]*
end
end
重要的事情在规则expr
和规则or_expr
中。我已经改变了or_expr
,所以它匹配除了评论之外的所有内容。如果我坚持当前的expr
规则,我会得到堆栈溢出。但是如果我切换它,它就没有 or_expr 和 gtor_expr 之间的选择它工作正常。
我对“选择”的理解是它将尝试按顺序评估它们。如果第一个选择失败,那么它将尝试第二个。在这种情况下,第一个选择显然能够成功,那么如果我包含一个永远不应该采用的第二个选择,为什么会出现堆栈溢出呢?