您的位置:首页 > 其它

上下文无关文法2

2015-07-30 19:04 423 查看

ambiguous

在表示”3 + 4”这样的表达式的时候,如果不区分digit和list,而仅使用string这一个非终结符号:

string -> string - string | string + string | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

可能出现二义性:用此文法对 9 - 5 + 2 进行推导,会有2颗语法分析树:

(9 - 5) + 2

9 - (5 + 2)

Example 2.7 Java语句的一个子集

stmt -> id = expr ;

   | if(expr) stmt

   | if(expr) stmt else stmt

   | while(expr) stmt

   | do stmt while(expr) ;

   | {stmt}

stmts -> stmts stmt

   | ε

这个文法符合Java的语法,但是像a=b=c这样的形式在这个文法中不允许出现

在stmt的定义中,分号总是出现在不以stmt结尾的产生式结尾,这样可以避免出现重复的分号

Practice 2.2.1

给出上下文无关文法:

S -> S S + | S S * | a

1)说明怎么用该文法生成串 aa+a*

  1>根据 S -> a ,可知a是S

  2>根据 S -> S S + ,由于2个a是S,可知aa+是S

  3>根据 S -> S S * ,由于aa+和a是S,可知aa+a*是S

2)略

3)生成的是后缀表示的,由a + * 组成的运算表达式 (不知道怎么答,不知道怎么证明)????

Practice 2.2.3

有无二义性?

1) S -> 0 S 1 | 0 1

  首先,这个文法只能生成长度为2n的串,前n个为0,后n个为1;

  任意一个 S[2n] 一定只能解释成 0(S[2n-2])1

2) S -> + S S | - S S | a

这个文法生成的是前缀表示的由a组成的二则运算表达式

??????

3) S -> S (S) S | ε

  ε是S,根据 S -> S (S) S , ()也是S;

  那么在用此文法推导 ()()时,会有2颗分析树:

    1. ε (ε) ()

    2. () (ε) ε

  所以存在二义性

4) S -> a S b S | b S a S | ε

  根据 S -> a S b S | b S a S | ε,ab 和 ba 是S

  观察发现,根据此文法推到出来的S一定含有偶数个字母;

  这个文法的二义性的一个可能的来源是:

    推导 a S1 b S2 b S3 时,S1 b S2 和 S2 b S3都可以推导为S

  然而这与 “S中一定有偶数个字母” 矛盾。

  而另一个歧义的来源与此同理

  所以不存在二义性

5) S -> a | S + S | S S | S * | (S)

  a + a a

Practice 2.2.4

1)后缀方式表示的算数表达式

  S -> SS+ | SS- | SS* | SS/ | number

  number -> number digit | digit

2)逗号分隔的左结合的标识符列表 ??????

3)逗号分隔的右结合的标识符列表 ??????

4)整数、标识符、四个二目运算符+-*/构成的算数表达式

  expr -> expr + term | expr - term | term

  term -> term * factor | term / factor | factor

  factor -> int | id |(expr)

  int -> int digit | digit

  id -> id letter | id digit | letter

5)在4)的基础上增加负号

????
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编译原理