我希望有人可以帮助我理解我的问题,这不是家庭作业,这只是我想要解决的一个例子问题。问题是定义一个语法,生成任意数量操作数的所有总和。例如,54 + 3 + 78 + 2 + 5 ......等我发现最容易定义问题的方式是:
non-terminal {S,B}
terminal {0..9,+,epsilon}
Rules:
S -> [0..9]S
S -> + B
B -> [0..9]B
B -> + S
S -> epsilon
B -> epsilon
epsilon is an empty string.
这似乎对我来说应该是正确的,因为您可以使用第一个规则递归地定义第一个数字,然后添加下一个整数,您可以使用第二个规则,然后使用第三个规则定义第二个整数。然后,您可以使用第四个规则返回到S并根据需要定义任意数量的整数。
这个解决方案在我看来是一个普通的语法,因为它遵守规则A - > aB或A - >但是在它为这个问题说的笔记中,使用常规语法无法定义这个问题。任何人都可以向我解释为什么我的尝试是错误的,为什么这需要没有背景?
感谢。
答案 0 :(得分:1)
虽然它不是正确的定义,但更容易认为对于非常规的语言,它需要平衡某些东西(如括号)。
您的问题可以通过仅在规则的两侧使用直接递归来解决,而不是在中间,因此可以使用常规语言来解决。 (同样,这不是正确的定义,但它更容易记住!)
例如,对于正则表达式引擎(如Perl或JavaScript),可以轻松编写/(\d+)(\+(\d+))*/
。
你可以这样写:
non-terminal {S,R,N,N'}
terminal {0..9,+,epsilon}
Rules:
S -> N R
S -> epsilon
N -> [0..9] N'
N' -> N
N' -> epsilon
R -> + N R
R -> epsilon
哪个应该正常工作。
答案 1 :(得分:0)
语言是正常的。正则表达式为:
((0|1|2|...|9)*(0|1|2|...|9)+)*(0|1|2|...|9)*(0|1|2|...|9)
终端是:{0,1,2,...,9,+}
“|”表示联合和*表示星形闭合
如果您需要使用您的语言中的“(”和“)”,那么它将不是常规的,因为它需要匹配括号。 示例上下文无关语法将是:
E->E+E
E->(E)
E->F
F-> 0F | 1F | 2F | ... | 9F | 0 | 1 | ... | 9