使用Citrus解析表达式语法的堆栈级别太深



我正在尝试使用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_exp之间进行选择,它就可以正常工作。

我对"选择"的理解是,它会尝试按顺序评估它们。如果第一个选项失败,则它将尝试第二个选项。在这种情况下,第一个选择显然是成功的,那么,如果我包含了永远不应该使用的第二个选择,为什么会出现堆栈溢出呢?

循环可能是因为gtand_expr->not_expr和not_expr->gtand_expr。

我认为你可以用代替not_expr规则

not_expr -> "NOT" not_expr | gtnot_expr

您应该使用regexp运算符尝试更简单的规则:

expr -> orexpr
orexpr -> andexpr ("OR" andexpr)*
andexpr -> notexpr ("AND" notexpr)*
notexpr -> "NOT"? atomicexpr
atomicexpr -> id | "(" expr ")"

相关内容

  • 没有找到相关文章

最新更新