问题:编写一个函数,要求输入一个由0..9, +, -, *, / ()组成的表达式字符串,计算结果, 如: (1 + 2 )* 3 , 为简单起见,不考虑大于10的整数。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

这是一个典型的语言识别问题。10年前,我有一位同事,他是IBM AS/400的专家,擅长RPG, CL程序的编写与维护;他认为能处理程序的程序是最高深的程序;当然在AS/400环境下,用RPG来编写这样的程序的确是很困难的。但即便是用C, 如果没有一点编译理论知识,也会觉得无从入手。

 

有一种很经典的语言分析方法,叫做递归下降法。解决这个问题首先需要把表达式精确地定义出来,这些定义称为语法规则:

 

表达式(exp)定义为 两个项(item)的加减,或者带括号的表达式

    exp : item + item

             item – item

              | item

            ;

 

项定义为 因子的乘除

       Item : factor * factor

              | factor / factor

              factor

 

       Factor : 0..9 | ( exp )

 

   

现在为每个规则配上一段解释代码(为了简单起见,部分局部变量及错误处理未定义:

   int exp()

      {

 i1 = item();

       op_char = current_char();

       next_char();

        if (op_char == ‘+’)

           return i1 + exp();

       else if (op_char == ‘-‘)

           return i1 – exp();

       else

           return i1;

}

 

item()

{

    f = factor();

op_char = current_char();

next_char();

if (op_char == ‘*’)

    Return f * factor();

Else if (op_char == ‘/’)

    Return f * factor();

Else

    Return f;

}

 

factor()

{

    c = current_char();

    next_char();

    If (c == ‘(‘)

        return exp();

    else

       return c – ‘<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0’;

}

 

这里由3个函数,分别是exp(), item()factor(), 分别对应上面的3个语法规则。还有两个辅助函数, current_char表示当前的字符, next_char把指针向下拨一次。这里忽略了实际应用中必须的错误检查。

 

看上去很简单,但是对于 SQL 这样的语言,递归下降分析法并不适用。对语法的任何修改,都需要小心地修改分析函数,更让人头疼的是,有些语法规则并不能消除左递归,从而写不出简单的递归函数。