我不是在寻找一个实现,只是伪代码,或者至少是一种有效处理这个问题的算法。我需要处理这样的语句:
(a) # if(a)
(a,b) # if(a || b)
(a+b) # if(a && b)
(a+b,c) # same as ((a+b),c) or if((a&&b) || c)
(a,b+c) # same as (a,(b|c)) or if(a || (b&&c))
因此+
运算符优先于,
运算符。 (所以我的+
就像数学乘法,,
是数学加法,但这只会令人困惑。)
我认为递归函数最好,所以我可以通过递归调用来处理嵌套括号。一旦函数返回,我也会处理错误处理,所以不用担心。我遇到的问题:
我只是不知道如何处理优先事项。我一看到return true
并且之前的值为真,我就可以,
。否则,我会重新运行相同的例行程序。加号实际上是一个布尔乘法(即true*true=true
,true*false=false
等......)。
错误检测:我已经考虑了几种处理输入的方案,但是我想检测很多丑陋的东西并向用户输出错误。我认为没有一种方案能够在代码中的统一(读取:集中)位置处理错误,这对于可维护性和可读性来说是很好的:
()
(,...
(+...
(a,,...
(a,+...
(a+,...
(a++...
在上面的“例程”中检测这些内容应该注意不好的输入。当然,每当我读取令牌时,我都会检查输入结束。
当然,如果有不匹配的括号,我可能会遇到读取全文文件的问题,但是嘿,人们应该避免使用tension。
编辑:啊,是的,我忘记了!
,它也应该像经典的非操作符一样可用:
(!a+b,c,!d)
对那些感兴趣的人进行了微小的更新:我有一个不知情的狂野,并从头开始编写我自己的实现。对于顽固派来说,so hence this question on codereview可能还不够。
答案 0 :(得分:6)
shunting-yard algorithm可以在相对较短的代码中轻松实现。它可以用来将你的例子中的中缀表达式转换为后缀表达式,并且后缀表达式的评估是Easy-with-a-capital-E(你不需要完全完成中缀到后缀的转换;你可以直接评估分流场的后缀输出,并随着你的进展积累结果)。
它处理运算符优先级,括号以及一元和二元运算符(并且可以通过一些努力来修改以处理中缀三元运算符,如许多语言中的条件运算符)。
答案 1 :(得分:2)
在yacc(野牛)中写下它变得微不足道。
/* Yeacc Code */
%token IDENTIFIER
%token LITERAL
%%
Expression: OrExpression
OrExpression: AndExpression
| OrExpression ',' AndExpression
AndExpression: NotExpression
| AndExpression '+' NotExpression
NotExpression: PrimaryExpression
| '!' NotExpression
PrimaryExpression: Identifier
| Literal
| '(' Expression ')'
Literal: LITERAL
Identifier: IDENTIFIER
%%
答案 2 :(得分:0)
可能有一个更好的(肯定有一个更简洁的)描述,但我多年前从本教程学习了如何做到这一点:
http://compilers.iecc.com/crenshaw/
对于非程序员来说这也很容易阅读(像我一样)。你只需要前几章。