常见的成员表达式写法
const o={a:1,b:2};
o.a;
o.b;
这里o.a是一个成员表达式,由两部分组成object o 和property a
写成巴克斯扩展范式,先匹配一个 ID 再匹配一个“.”成员运算符,再接一个ID。
memberExpr:ID '.' ID;
o.a成功解析出来。
可该范式无法解决a.b.c.d这样的成员表达式嵌套问题
因为一个成员运算符 允许跟在ID后,也可以跟在一个成员表达式后,如果我们把巴克斯扩展范式写成这样,那么就遇到了著名的左递归问题。
memberExpr:(ID|memberExpr) '.' ID
这条规则在递归下降解析中,写成如下形式:
function matchMemberExpr(){
if(matchID()||matchMemberExpr()){
if(matchDot()&& matchID();){
return new MemberExpr();
}
}
}
matchMemberExpr被不断调用,最终导致栈溢出。好在我们由固定的套路来解决这个问题--左递归文法改写。
文法改写由两个要点,1.把左递归转为右递归
memberExpr: memberExpr '.' ID
|ID '.' ID;