为了实现自顶向下的语法分析器,需要将文法的
1.左递归消除 (完成)
2.提取公因子 (完成)
3.计算first,follow集合(完成)
4.得到LL(1)预测分析表 (100322完成)
如下面的文法:
E = E + T | T
F = ( E ) | id
T = T * F | F
javascript描述的文法规则为:
[ [{tag: "E"},{tag: "E"},{tag: "+",end: "true"/*终结符*/},{tag: "T"}],//E->E+T [{tag: "E"},{tag: "T"}],//E->T [{tag: "T"},{tag: "T"},{tag: "*",end: "true"},{tag: "F"}],//T->R*F [{tag: "T"},{tag: "F"}],//T->F [{tag: "F"},{tag: "(",end: "true"},{tag: "E"},{tag: ")",end: "true"}],//F->(E) [{tag: "F"},{tag: "id",end: "true"}]//F->id ]
tag用来表示符号,无论终结或者非终结,end表示符号为终结符号,用数组来表示一条文法规则,表示从数组第一个元素可以推导出数组第二个元素到最后连接的符号串。
需要消除左递归变化为(x表示空):
E = T E'
E' = x | + T E'
F = ( E ) | id
T = F T'
T' = x | * F T'
代码结构:
Ext.ux.compiler.Grammar = function (g, startG) { //| 拆分 //e->s|t //拆分为两条 //e->s //e->t }; Ext.override(Ext.ux.compiler.Grammar, { //消除左递归并提取公因子 leftRecurEliminate: function () { /* 去除公共前缀 */ }, //得到符号ex的first集合 _first: function (ex) {}, //得到符号ex的follow集合 _follow: function (ex) {}, //得到符号ex后紧跟的符号,可以为文法结尾符号$ getFollowSymbols: function (ex) {}, //得到一组文法的公共前缀 getCommonPrefix: function (gs) {}, //字符串序列化显示 serialize: function () {} });