Closed. This question needs details or clarity。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
                        
                        3年前关闭。
                                                                                            
                
        
我想用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()函数。
我想知道如何处理“ ,“ ,“ 。
还有,什么意思
    [; stmts]和
    {“ |“ }

最佳答案

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

您从哪里得到这种语法的?不幸的是,人们用BNF编写的语法略有不同,但并没有告诉您他们在使用什么约定。选中Wikipedia for BNF以查看一些变化。

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

[;stmts]


并且使用大多数语言允许语句序列的知识,我猜想[ X ]的意思是“序列中的0个或多个X”,这里的具体解释是“ 0个或更多的语句,每个语句后面都带有';'” 。

给定一个明显的惯例,将概念X的BNF规则引用为<X>,此语法在此处是无效的。作者草率,应该写[; <stmts>]

看起来,以这种BNF样式指示文字字符的约定是在不使用BNF元语法中使用的文字时使用文字字符。该语法使用的BNF元语法字符似乎是

  < >   ( ) [  ]  {  }  '


使用->作为特殊标记。不在此集合中的任何文字字符都将被简单地写成它自己。此集合中的所有文字字符都必须加引号。这种解释似乎可以解释大多数语法,但-除外。这样的规则可能会使语法看上去对作者来说更清晰(或类似),但会使读者难以理解。

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

关于

{<letter>|<const>}


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

我将[ X ]{ X }都解释为“ 0或更多”的事实表明我的猜测是错误的。为什么使用两个不同的符号表示同一件事?所以也许他们的意思是不同的;也许[ X ]表示“一个或多个”。我不能只看语法就知道。

对于这么小的语法,我不得不猜测太多,这真是个坏消息。我认为该语法作者选择的约定对读者不利。对于初学者而言,这尤其是个坏消息,因为它使本来就很棘手的话题更加混乱。

我谨代表任何撰写此语法并将其提供给您的人致歉。

但是,上课。在许多情况下,BNF语法写得很乱。由于您无法修复作者,因此您需要学习解释所获得的知识。 mm

10-08 19:38