移进规约冲突一例

最近需要给REVOKE语句增加一个新的语法形式,原来的语法形式如下:

 

RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target

            FROM grantee_list opt_cascade_restrict

 

opt_revoke_grant_option:

             GRANT OPTION FOR

            | /*EMPTY*/

 

原计划按如下形式增加新的语法形式:

 

RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target

            FROM grantee_list opt_cascade_restrict

            |REVOKE privileges2 FROM grantee_list

 

opt_revoke_grant_option:

             GRANT OPTION FOR

            | /*EMPTY*/

 

通过bison编译,发现移进/规约冲突(SHIFT/REDUCT CONFLICT),查看output文件如下:

 

State 49 conflicts: 6 shift/reduce

查看State 49如下:

 

state 49

 

  1386  RevokeStmt: REVOKE . opt_revoke_grant_option privileges ON privilege_target FROM grantee_list opt_cascade_restrict

  1387           | REVOKE . privileges2 FROM grantee_list opt_grant_admin_option

 

……

EXECUTE   shift, and go to state 572

GRANT     shift, and go to state 573

INSERT    shift, and go to state 574

 

$default  reduce using rule 1433 (opt_revoke_grant_option)

……

 

由于opt_revoke_grant_option可以为空(EMPTY),则在EMPTY时,既可以采用规则1386对opt_revoke_grant_option进行规约(见红色字体),也可以采用规则1387移进到privileges2。

 

通过增加一个新的规则privileges_and_grantee来解决该问题:

RevokeStmt: REVOKE opt_revoke_grant_option privileges_and_grantee

 

privileges_and_grantee:

            privileges ON privilege_target

            FROM grantee_list opt_cascade_restrict

            |privileges2 FROM grantee_list

 

 

上面的修改会改变语法形态,由于opt_revoke_grant_option不一定是EMPTY,还可能是GRANTOPTION FOR,所以,第二条语法规则会增加如下语法形态:

 

REVOKE GRANT OPTION FOR privileges2 FROM grantee_list

 

虽然可以通过判断opt_revoke_grant_option是否为空在语义分析时来报错,但语法形态不符合我们的本意。

 

拆分语法规则:

 http://blog.csdn.net/shujiezhang

另外可以通过拆分语法规则的方式,来解决该问题,可以将opt_revoke_grant_option语法规则拆分掉,那么在privileges之前就不再产生规约,从而屏蔽掉移进规约冲突。

 

增加一个新的语法规则,revoke_privilege来取代原有的移进规约冲突的位置:

 

RevokeStmt: REVOKE revoke_privileges ON privilege_target

            FROM grantee_list opt_cascade_restrict

            |REVOKE revoke_privileges FROM grantee_list

 

revoke_privileges:

            privileges

            |GRANT OPTION FOR privileges

            |privileges2

 

 

你可能感兴趣的:(数据库)