扩展SQLite语法时遭遇解析冲突,寻求解决方法
解决SQLite Lemon解析器的CREATE TABLE语法冲突问题
冲突原因
你遇到的是移进-归约冲突:当解析器读到CREATE后,无法确定是直接将其归约为createorreplace(对应CREATE分支),还是继续移进OR来匹配CREATE OR REPLACE分支。同时temp规则允许空令牌,进一步让解析器无法通过后续token提前判断路径,最终触发冲突。
解决方案:显式拆分语法规则
直接拆分create_table规则,将CREATE和CREATE OR REPLACE的情况分开定义,消除解析器的二义性判断。这种方法完全保留OR REPLACE的可选性,同时支持后续跟随TEMP(或省略TEMP),符合你的需求。
修改后的规则如下:
cmd ::= create_table create_table_args table_properties_args. // 拆分后的create_table规则,覆盖两种createorreplace情况 create_table ::= CREATE temp(T) TABLE ifnotexists(E) nm(X) dbnm(Y). { disableLookaside(pParse); int C = 0; // 对应原createorreplace的A=0 // 原有的逻辑代码 } create_table ::= CREATE OR REPLACE temp(T) TABLE ifnotexists(E) nm(X) dbnm(Y). { disableLookaside(pParse); int C = 1; // 对应原createorreplace的A=1 // 原有的逻辑代码 } // 保留原temp规则不变,仍支持TEMP或省略 %type temp {int} temp(A) ::= TEMP. {A = pParse->db->init.busy==0;} temp(A) ::= . {A = 0;}
为什么这个方法有效
拆分后,解析器读到CREATE后会直接根据下一个token做明确判断:
- 如果下一个token是
OR,则匹配CREATE OR REPLACE分支; - 如果下一个token是
TEMP或TABLE,则匹配CREATE分支。
完全消除了原规则中解析器需要猜测的场景,Lemon解析器就能生成无冲突的语法树。
内容的提问来源于stack exchange,提问作者benjist
相关产品推荐
相关产品推荐

