ECMAScript词法语法分词时如何规范确定goal symbol?
ECMA-262 goal symbol 确定规则及实践方案
核心概念说明
goal symbol 是ECMAScript词法文法中用于解决分词歧义的核心标记,用来指定词法分析器当前的识别规则优先级,正好可以解决你区分宏调用位置的需求。
确定goal symbol的规范规则
1. 常用goal symbol分类
你需要用到的主要有三类:
- InputElementDiv:默认分词模式,遇到斜杠时优先识别为除法运算符,所有普通表达式场景都使用该模式
- InputElementRegExp:正则优先模式,遇到斜杠时优先识别为正则字面量的开头,仅在期望新表达式开始的场景使用
- InputElementTemplateTail:模板字符串模式,所有字符除了
`和${之外都识别为模板普通字符,仅在解析模板字符串的非插值段时使用
2. 模式切换规则
你可以直接按照以下逻辑实现模式切换:
- 初始化分词时,起始位置默认处于「期望新表达式开始」状态,使用InputElementRegExp模式
- 每完成一个token的识别后,根据上一个token的类型切换下一个token的识别模式:
- 上一个token为以下类型时,下一个使用InputElementRegExp模式:
- 标点符号:
(,{,[,;,,,<,>,<=,>=,==,!=,===,!==,+,-,*,%,**,<<,>>,>>>,&,|,^,!,~,&&,||,??,?,:,=,+=,-=,*=,%=,**=,<<=,>>=,>>>=,&=,|=,^=,=> - 关键字:
yield,await,return,throw,case,delete,void,typeof,new,in,instanceof
- 标点符号:
- 其他所有场景,下一个使用InputElementDiv模式
- 上一个token为以下类型时,下一个使用InputElementRegExp模式:
- 模板字符串特殊处理逻辑:
- 遇到模板字符串开头
`时,切换为InputElementTemplateTail模式 - 解析过程中遇到
${时,先输出当前模板普通字符段token,切换回普通表达式模式(${后默认期望新表达式开始,使用InputElementRegExp) - 解析完
${}内的表达式、遇到匹配的}时,再次切回InputElementTemplateTail模式,直到遇到模板字符串结束的`
- 遇到模板字符串开头
对应你的宏调用校验逻辑
你只需要判断识别到macro标识符的时刻,满足以下两个条件,即为合法的宏替换位置:
- 当前分词模式不是InputElementTemplateTail
- 当前没有处于正则字面量的内部识别流程
四个示例场景的匹配结果完全符合你的要求:
macro(); // 普通表达式模式,合法 foo = /macro()/; // 处于正则字面量内部,非法 foo = `macro()`; // 处于模板字符串普通段,非法 foo = `some text ${macro()}`; // ${}内为普通表达式模式,合法
内容的提问来源于stack exchange,提问作者Lane Sun
相关产品推荐
相关产品推荐

