1

我有一段 Yacc 表示法的语法片段:

stylesheet
: [ CHARSET_SYM STRING ';' ]?
  [S|CDO|CDC]* [ import [ CDO S* | CDC S* ]* ]*
  [ [ ruleset | media | page ] [ CDO S* | CDC S* ]* ]*
;

如何在 Irony 中实现这个片段?我找不到任何等效的?,这意味着在 Yacc 中出现 0 或 1 次。

4

2 回答 2

2

你可以用BnfTerm.Q方法来表示'?' (0 或 1 次出现)。?这是一个合理的设计决定,因为与+and不同, C# 不允许您编写运算符的自定义实现*

从Irony Wikibook 上的Non Terminals 页面:

在传统的 BNF 表示法中,“?”、“+”和“*”字符分别用于表示“0 或 1 次”、“1 次或多次”和“0 次或多次”。在 Irony 中,它的做法略有不同。您可以对“+”和“*”使用基语法类中的 MakePlusRule 和 MakeStarRule 方法,也可以直接对规则中的术语使用 Q()、Plus() 和 Star() 方法。

于 2014-05-27T09:56:22.317 回答
1

作者说现在需要一个额外的 AST 节点来实现这个目的。因此,例如,您可以将以下内容替换为规则中的可选术语:

new NonTerminal("OptionalTermName", Empty | TermThatShouldBeOptional)

http://irony.codeplex.com/discussions/550979

我想知道它是否可以简化为:

(Empty | TermThatShouldBeOptional)

重载会创建一个 BNF 术语,而不是一个 NonTerminal 节点,当直接与其他 BNF 术语连接时,它可能会丢失一些层次信息,具体取决于实现。我没有进一步调查。

于 2014-12-19T18:26:13.343 回答