如何将某些表达式抽象为 BNF?
例如:
waldo:=fern+alpha/-beta^gamma;
上面的算术表达式可以通过这个BNF抽象出来(与标准BNF可能有一些差异,暂时忽略它):
AEXP = AS $AS ;
AS = .ID ':=' EX1 ';' ;
EX1 = EX2 $( '+' EX2 / '-' EX2 ) ;
EX2 = EX3 $( '*' EX3 / '/' EX3 ) ;
EX3 = EX4 $( '^' EX3 ) ;
EX4 = '+' EX5 / '-' EX5 / EX5 ;
EX5 = .ID / .NUMBER / '(' EX1 ')' ;
.END
但是EX1~EX5
抽象对我来说不是那么直观。(我不太明白它们是如何制作的)
规范化此类表达式时有什么步骤要遵循吗?
For example :
waldo:=fern+alpha/-beta^gamma;
The above arithmetical expression may be abstracted by this BNF(there may be some difference from standard BNF,but lets ignore it for now):
AEXP = AS $AS ;
AS = .ID ':=' EX1 ';' ;
EX1 = EX2 $( '+' EX2 / '-' EX2 ) ;
EX2 = EX3 $( '*' EX3 / '/' EX3 ) ;
EX3 = EX4 $( '^' EX3 ) ;
EX4 = '+' EX5 / '-' EX5 / EX5 ;
EX5 = .ID / .NUMBER / '(' EX1 ')' ;
.END
But the EX1~EX5
abstraction is not so intuitive to me.(I don't quite understand how they are crafted in the first place)
Is there any steps to follow when normalizing such expressions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以将此表示法直接翻译为 EBNF。
命名类别 EX1 到 EX5 并不是指定运算符优先级的常见方法。事实上,恕我直言,这是一个很好的选择,特别是在某些具有 15 个或更多优先级的语言中,例如 C 和 C++。 :)
您可以将它们重命名为表达式、术语、因子、主要等(或任何对您有意义的术语)。
附录
如果您需要将上述内容翻译成更传统的 EBNF,我会这样做:
我使用“*”表示零个或多个,“+”表示一个或多个,使用“?”为可选。我认为这里处理运算符优先级的方式非常酷。
附录 2:
请注意:EX3 的规则似乎是错误的。现在的情况你可以得到像这样的解析树
所以写
a^b^c^d^e^f
可能意味着a^(b^c)^d^(e^ f)
。但事实上还有其他方法可以制作这棵树。语法有歧义。看来语法的设计者希望使
^
运算符具有右关联性。但要做到这一点,规则应该是现在语法不再含糊了。看看
a^b^c^d^e^f
的推导现在必须如何进行:现在
a^b^c^d^e^f
只能解析为a^(b^(c^(d^(e^f))))
另一种方法是将规则重写为
EX3 => EX4 ('^' EX4)*
并有一条辅助规则,表示“OBTW 插入符号是右关联的”。You can translate this notation to EBNF directly.
Naming categories EX1 through EX5 is not an uncommon way of specifying operator precedence. In fact it is a good one, IMHO, especially in some languages that have 15 or more precedence levels, like C and C++ do. :)
You can rename them to expression, term, factor, primary, etc. (or whatever terms make sense to you).
ADDENDUM
If you need a translation of the above into more traditional EBNF, here is how I would do it:
I use '*' for zero or more, '+' for one or more, and '?' for optional. It is pretty cool how operator precedence is handled here, I think.
ADDENDUM 2:
Please note: It appears that the rule for EX3 is wrong. The way it stands now you can get parse trees like this
So writing
a^b^c^d^e^f
could meana^(b^c)^d^(e^f)
. But in fact there are other ways to make this tree. The grammar is ambiguous.It appears the designer of the grammar wanted to make the
^
operator right-associative. But to do so, the rule should have beenNow the grammar is no longer ambiguous. Look how the derivation of
a^b^c^d^e^f
MUST now proceed:Now
a^b^c^d^e^f
can ONLY parse asa^(b^(c^(d^(e^f))))
An alternative is to rewrite the rule as
EX3 => EX4 ('^' EX4)*
and have a side rule saying "OBTW the caret is right associative."