处理条件语句

时间:2011-06-03 15:11:49

标签: c++ algorithm parsing c++11

我不是在寻找一个实现,只是伪代码,或者至少是一种有效处理这个问题的算法。我需要处理这样的语句:

(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))

因此+运算符优先于,运算符。 (所以我的+就像数学乘法,,是数学加法,但这只会令人困惑。)

我认为递归函数最好,所以我可以通过递归调用来处理嵌套括号。一旦函数返回,我也会处理错误处理,所以不用担心。我遇到的问题:

  1. 我只是不知道如何处理优先事项。我一看到return true并且之前的值为真,我就可以,。否则,我会重新运行相同的例行程序。加号实际上是一个布尔乘法(即true*true=truetrue*false=false等......)。

  2. 错误检测:我已经考虑了几种处理输入的方案,但是我想检测很多丑陋的东西并向用户输出错误。我认为没有一种方案能够在代码中的统一(读取:集中)位置处理错误,这对于可维护性和可读性来说是很好的:

    ()
    (,...
    (+...
    (a,,...
    (a,+...
    (a+,...
    (a++...
    

    在上面的“例程”中检测这些内容应该注意不好的输入。当然,每当我读取令牌时,我都会检查输入结束。

  3. 当然,如果有不匹配的括号,我可能会遇到读取全文文件的问题,但是嘿,人们应该避免使用tension

    编辑:啊,是的,我忘记了!,它也应该像经典的非操作符一样可用:

    (!a+b,c,!d)
    

    对那些感兴趣的人进行了微小的更新:我有一个不知情的狂野,并从头开始编写我自己的实现。对于顽固派来说,so hence this question on codereview可能还不够。

3 个答案:

答案 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/

对于非程序员来说这也很容易阅读(像我一样)。你只需要前几章。