规则集的BNF语法

时间:2014-08-21 19:06:07

标签: context-free-grammar bnf automata formal-languages

我遇到了问题

(a)使用BNF规则给出一个语法,用“witless”语言构建一个程序。一个没有思维的程序必须遵循规则:程序必须以“endstart”一词开头和结尾。该语言有三种类型的语句:print,read和compute。这些语句可以按任何顺序发生,只是打印只能在compute语句之后立即发生。这是任何非空的大写字母串。您的BNF也必须定义。合法无智能程序的一个示例是:endstart读取SAM读取TED计算计算打印FRED计算读取TIM endstart(b)您的语法是否模糊不清?解释你的答案。

我提出了以下解决方案。但我需要确保它是正确的。

<witless_program>::=endstart <statement> endstart
<statement>::=<read>|<compute>
<read>::='read' <var>|<statement>
<print>::='print' <var>
<compute>::='compute' | 'compute' <print>|<statement>
<var>::=<letter> | <var><letter>
<letter>::=A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z

语法似乎毫不含糊。我是对的吗?

1 个答案:

答案 0 :(得分:1)

看起来你的语法有点偏差。假设有人说选择如下的推导:

program --> endstart <statement> endstart
--> endstart <read> endstart
--> endstart read <var>

使用当前语法,您将无法使用递归来继续语言中的句子,因为在完全派生非终端 var 之后,没有引用回到非终端语句

我会考虑以下语法来满足您的需求:

<statement> --> <read> | <compute>
<read>      --> read <var> <statement> | read <var>
<compute>   --> compute <print> <statement> | compute <print> | compute <statement> | compute
<print>     --> print <var>
<var>       --> <letter> | <letter><var>
<letter>    --> A|B|C|...

现在让我们得出句子&#34; endstart读取SAM读取TED计算计算打印FRED计算读取TIM endstart&#34;使用LHS替代:

program --> endstart <statement> endstart
--> endstart <read> endstart endstart
--> endstart read <var> <statement> endstart
--> endstart read <letter><var> <statement> endstart
--> endstart read S<var> <statement> endstart
--> endstart read S<letter><var> <statement> endstart
--> endstart read SA<var> <statement> endstart
--> endstart read SA<letter> <statement> endstart
--> endstart read SAM <statement> endstart
--> endstart read SAM <read> endstart
--> endstart read SAM read <var> <statement> endstart
--> endstart read SAM read <letter><var> <statement> endstart
--> endstart read SAM read T<var> <statement> endstart
--> endstart read SAM read T<letter><var> <statement> endstart
--> endstart read SAM read TE<var> <statement> endstart
--> endstart read SAM read TE<letter> <statement> endstart
--> endstart read SAM read TED <statement> endstart
--> endstart read SAM read TED <compute> endstart
--> endstart read SAM read TED compute <statement> endstart
--> endstart read SAM read TED compute <compute> endstart
--> endstart read SAM read TED compute compute <print> <statement> endstart
--> endstart read SAM read TED compute compute print <var> <statement> endstart
... play the same game to spell out FRED ...
--> endstart read SAM read TED compute compute print FRED <statement> endstart
--> endstart read SAM read TED compute compute print FRED compute <statement> endstart
--> endstart read SAM read TED compute compute print FRED compute <read> endstart
--> endstart read SAM read TED compute compute print FRED compute read <var> endstart
... play the same game to spell out TIM ...
--> endstart read SAM read TED compute compute print FRED compute read TIM endstart

现在我们有了一个推导,可以解决歧义问题。你应该问的问题是语法是否有一个额外的解析树。对此的诀窍是查看语法并尝试识别任何具有包含自身实例的产品的非终端,这些实例可能导致一条或另一条路径。认为

<statement> --> <statement><statement> | some_terminal

对于这种生产,解析器必须决定哪条路径(在这种情况下,首先要替换哪条语句)。如果你的语法没有具有这种属性的作品,那么它通常是明确的。

并回答你的问题 - 不,纠正的语法并不含糊。