【问题标题】:How do you write a grammar for this arithmetic expression?你如何为这个算术表达式编写语法?
【发布时间】:2016-10-30 09:36:39
【问题描述】:

这是我的语言的算术表达式:ADD 100 MUL 5 DIV 10 SUB 7 MOD 10 4

其中ADD = 加法,SUB = 减法,MUL = 乘法,DIV = 除法,MOD = 模数。

上面的表达式也可以改写成标准的100 + (5 * (10 / (7 - (10 % 4)))),括起来的括号用来标记操作的顺序。

这与标准完全不同,因为评估从最右边的操作开始,即MOD 10 4,然后将其结果用于评估下一个操作,即SUB 7 2,其中2是模运算的结果。此语法不需要括号。

我从https://ruslanspivak.com/lsbasi-part6/ 得到了标准符号的语法,这里是:

 <expr> := <term> ((ADD|SUB) <term>)*
 <term> := <factor> ((MUL|DIV|MOD) <factor>)*
 <factor> := integer

在我的语言中,我对写算术运算的语法一无所知。上面的语法需要修改吗?还是我需要写一个全新的语法?

【问题讨论】:

  • 写语法就像写程序一样。您提出了一些代码/语法片段,您决定它是否符合您的预期,如果没有,请更改它直到它符合您的要求。如果您了解语法,这应该不难。如果你不这样做,经验将帮助你理解它们。您尝试过如何编写自己的语法或测试此语法是否可行?
  • 我已经成功地编写了解析标准算术表达式(+、-、*、/、%)的方法和代码,就像指南所做的那样,我只是将 Python 代码转换为 C#。通过将指南中的语法修改为&lt;expr&gt; := (ADD|SUB) &lt;term&gt; &lt;term&gt;,我还成功地使用我的语言解析了单个操作,但我一直在解决如何解析具有多个操作的表达式。

标签: parsing syntax grammar interpreter


【解决方案1】:

我通过分析代码中每个产品的执行情况设法解决了这个问题。令我惊讶的是,我忘记在&lt;factor&gt; 中包含&lt;expr&gt; 产品。稍微改变我的代码我移动某些条件,我能够解析上面的示例表达式。这是我的语言中算术表达式的语法:

<expr> := ((ADD|SUB) <term> <term>)* | <term>
<term> := ((MUL|DIV|MOD) <factor> <factor>)* | <factor>
<factor> := INTEGER | <expr>

&lt;factor&gt; 中的 &lt;expr&gt; 产生式可以进行多个操作,因为它会回到开头解析下一个操作。

【讨论】:

  • 这真的有效吗?在我看来,它可以无限扩展 expr 到 term 到 factor 到 expr ...我认为你还有一些工作要做。
  • 我使用ironcreek.net 生成了一个解析树,括号中的短语:[&lt;expr&gt; [ADD][&lt;term&gt; [&lt;factor&gt; 100]][&lt;term&gt; [MUL][&lt;factor&gt; 5][&lt;factor&gt; [&lt;expr&gt; [&lt;term&gt; [DIV][&lt;factor&gt; 10][&lt;factor&gt; [&lt;expr&gt; [SUB][&lt;term&gt; [&lt;factor&gt; 7]][&lt;term&gt; [MOD][&lt;factor&gt; 10][&lt;factor&gt; 4]]]]]]]]] 据我所知,语法是正确的。是什么让你不这么认为?
  • 你没有“生成”解析树;看来你发明了一个你的想象力并简单地写下来。发明答案不是测试解析器的方法。用你的语法构建一个真正的解析器,并用它来构建一个解析树。你会发现你的语法有错误。 (看到我评论中的“1”吗?这意味着其他人同意我的观点)。要么使用真正的解析器生成器(ANTLR 会做),要么手写一个递归下降解析器(参见stackoverflow.com/questions/2245962/…)。
  • 我确实为此用 C# 编写了一个 RDP,语法检查出来了。它正确解析了表达式并返回了结果。请指出我的语法错误。
  • 我做到了。仔细阅读我的评论。
猜你喜欢
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多