C代码

时间:2016-10-22 12:48:09

标签: c parsing recursion recursive-descent

我想在C中制作递归下降解析器 鉴于条件如下:

<prg> -> <stmts>
<stmts> -> <stmt> [;stmts]
<stmt> -> <assign> | <if>
<if> -> if '(' <expr> ')' ('{' <stmts> '}' | <stmt>)
<expr> -> <term> {(+ | -) <term>
<term> -> <factor> {(* | / ) <factor>}
<factor> -> <const> | <id> | '(' <expr> ')'

<id> -> <letter> {<letter>|<const>}
<letter> -> a|b|c
<digit> -> 0|1|2

我得到了addChar(),getChar(),lex()函数。 我想知道如何处理&#34;&lt;&#34; stmt&gt;,&#34;&lt;&#34; if&gt;,&#34;&lt;&#34; letter&gt;。 另外,是什么意思     [; stmts]和     {&#34;&LT;&#34;字母GT; |&#34;&LT;&#34;&常量GT;} ?

1 个答案:

答案 0 :(得分:2)

how to write recursive descent parsers上查看我的答案:

你从哪里得到这个语法?不幸的是,人们在BNF中用各种略有不同的符号来编写语法,并且不告诉你他们正在使用什么约定。检查Wikipedia for BNF以查看一些变体。

通常,您必须了解BNF及其变体,以及您对BNF要描述的语言的理解,并解释BNF以猜测它们的实际含义。 [那是愚蠢的; BNF的目的是消除所有猜测]。关于

[;stmts]

并且使用大多数语言允许一系列语句的知识,我猜[ X ]表示序列中的&#34; 0或更多X&#34;这里的具体解释是指&#34; 0或更多的陈述,每个陈述前面都有一个&#39 ;;&#39;&#34;。

鉴于概念X的BNF规则被引用为<X>的适当约定,此语法在此处被破坏;作家很草率,应该写[; <stmts>]

在这种BNF样式中指示文字字符的惯例似乎是当它不是BNF metasyntax中使用的字符时使用文字字符。使用的BNF metasyntax字符是这个语法似乎是

  < >   ( ) [  ]  {  }  ' 

->作为特殊标记。不在此集合中的任何文字字符都只是自己写的;必须引用此集合中的任何文字字符。除了-之外,这种解释似乎解释了大部分语法。这样的规则可能会使语法看起来更清晰(某种程度)给作者,但让读者难以理解。

无论如何,这解释了为什么[; stmts]不是[ ';' stmts]。恕我直言,正确的约定是总是引用文字字符;然后读者永远不必猜测。

关于

{<letter>|<const>}

再次使用我们对BNF变体的理解,并且知道标识符通常是字母和数字的序列,我得出结论{ X }&#34;表示&#34; 0和更多的X&#34;并且这里的意图是&#34; 0或更多字母或数字&#34;。

我将[ X ]{ X }解释为含义&#34; 0或更多&#34;表明我猜错了;为什么用两种不同的符号来表示同一件事?所以也许他们意味着不同的东西也许[ X ]表示&#34;一个或多个&#34;。我只能通过查看语法来告诉我。

我必须为这么小的语法猜这么多才是坏消息。我认为这个语法作者选择的约定对读者来说是一种伤害。这对于初学者来说尤其是坏消息,因为它增加了一个已经很棘手的主题的混乱。

代表那些写过这个语法并把它交给你的人,我道歉。

但是,请接受教训。在很多情况下,BNF语法都是写得很糟糕。既然你无法修复作者,你需要学会解释你得到的东西。长号。