首先,我知道我知道。这个问题之前有过一段时间被问过,但大多数答案都是在其他主题上得到的,只能部分回答我的问题。
我正在做一些可以解析C表达式的东西。 这包括表达式,例如(某些例子)
1) struct1.struct2.structarray[283].shd->_var
2) *((*array_dptr)[2][1] + 5)
3) struct1.struct2.struct3.var + b * c / 3 % 5
问题是......我需要快速做到这一点。尽可能快,即使它使代码变得丑陋 - 显然,速度改进必须是有形的。原因是它被解释了。它需要很快......
我有很多问题,我可能会根据你的答案提出更多问题。但无论如何......
首先,我知道“运营商优先级”。例如,在C编译器中实现的算法将为运算符分配优先级编号并基于该值来评估表达式。 我已经查阅了这张表:http://en.wikipedia.org/wiki/Operators_in_C_and_C++#Operator_precedence
现在,这很酷但是......我想知道一些事情。 我的主要问题是......你如何实现这一目标是最快的?
我已经考虑过了......(请注意我所说的程序实际上解析了包含这些表达式的文件,并且不将支持所有C运算符)
1)将表达式字符串放入数组中,将每个操作符位置存储在数组中,然后从最高优先级的运算符开始解析所有这些垃圾。例如,如果我有str =“2 * 1 + 3”,那么在检查所有存在的运算符后,我将检查str [1]处的位置,并检查左右,执行操作(此处相乘)然后用结果代替表达式并再次评估。
我看到的问题是......说expr中的两个运算符具有相同的优先级
例如:var1 * var2 / var3 / var4
因为*和/都有相同的优先级,如何知道在哪个位置开始解析?当然这个例子非常直观,但我可以通过巨大的表达来解决这个问题。
2)这甚至可以非递归吗?通常递归意味着更慢,因为多个函数调用设置自己的堆栈帧,重新初始化东西等等。
3)如何区分一元运算符和非一元运算符?
例如:2 + * a + b * c
有解除引用操作和乘法操作。直觉上我知道如何做到这一点,但我不确定。我宁愿对此提出建议(我认为:检查右侧或左侧成员之一是否是操作员,如果是,那么它是否是一元的?)
4)我没有从右到左评估表达式。似乎不自然。更多我不知道它意味着什么。你会举个例子吗?为什么这样???
5)你有更好的算法吗?实现它的更好的想法?
目前,这几乎与我的想法相吻合。 顺便说一句,这不是一个功课。这是实用的东西。
谢谢!