编译器语法推导(1)基本定义
在文法定义中,我们讲到了两个概念,分别是终结符号
和非终结符号
。回忆一下二者。
- 终结符号
词法单元,不可再变
- 非终结符号
词法变量,尚未确定
比如
stmt -> if(expr) stmt else stmt
其终结符号为
if, (), {}
非终结符号为
expr, stmt
术语
- 语言
从开始符号推导得到所有终结符号串的集合称为该文法定义的语言。
比如在语法定义的例子中,从一个9-5+2
、3-1
或7
这样一个表达式推导出所有的终结符号
为
+ - 0 1 2 3 4 5 6 7 8 9
这样就可以推导完成。
反过来,如何判断9-5+2
是属于上述推导出来的语言呢?
首先看看产生式
list -> list + digit | list - digit | digit
然后把9-5+2
中的终结符
全部放入产生式
中
9
是digit
,所以9
是list
9-5
是中间段list-digit
的表达式,5
是digit
, 所以9-5
也是list
- 然后再看
+2
部分,由于前面9-5
已经是list
,所以9-5+2
也就是list+2
,然后2
是digit
,所以9-5+2
也就是list + digit
,也是list
至此可以说,9-5+2
根据产生式右部
的定义可以推导出左部
,也就是说9-5+2
就是产生式所定义的语言
。
语法分析
书上定义(读起来很拗口,说不定越看越糊涂)
语法分析(Parsing)的任务是:接收一个终结符号串作为输入,找出从文法的开始符号推导出这个串的方法。如果不能从文法的开始符号推导得到该终结符号串,则报告该终结符号串包含的语法错误。
回到上面的例子,来对应书中的每一句话
-
接收一个终结符号串作为输入
对应9-5+2
-
找出从开始符号推导出这个串的方法
对应 找出9-5+2
的产生式
list-> list + digit | list - digit | digit; digit -> 0|1|2|3|4|5|6|7|8|9
- 如果不能从文法的开始符号推导得到该终结符号串,则报告终结符号串包含的语法错误。
反例, 9-+5+2
对应 无法最后得到list
关于编译原理中产生式的常见表达方法
很多时候,产生式并不会像上面的所述的那么容易看出来。比如下面
call -> id(optparms)
optparams -> params | e
params -> params, param | param
注意:
e是
ϵ
\epsilon
ϵ
表示Empty,即空集,也就是什么都没有。
这里还是可以用语法定义中对产生式的定义和替换
的方法来看
call可以具有以下形式:id(optparams)
其中optparams可以具有以下形式:params 或 空集
其中params可以具有以下形式:params, param 或 param
举例
max(x,y)
是上述产生式的语言