如果标题不够清楚,我对词法分析和解析很抱歉。
基本上,我使用 Jison 来解析一些文本,并且试图让词法分析器理解缩进。这是有问题的一点:
(\r\n|\r|\n)+\s* %{
parser.indentCount = parser.indentCount || [0];
var indentation = yytext.replace(/^(\r\n|\r|\n)+/, '').length;
if (indentation > parser.indentCount[0]) {
parser.indentCount.unshift(indentation);
return 'INDENT';
}
var tokens = [];
while (indentation < parser.indentCount[0]) {
tokens.push('DEDENT');
parser.indentCount.shift();
}
if (tokens.length) {
return tokens;
}
if (!indentation.length) {
return 'NEWLINE';
}
%}
到目前为止,几乎所有这些都按预期工作。一个问题是我尝试返回一组DEDENT
标记的行。似乎 Jison 只是将该数组转换为一个字符串,这导致我得到一个解析错误,例如Expecting ........, got DEDENT,DEDENT
.
我希望我能做的就是手动将一些DEDENT
令牌推送到堆栈上。也许有类似的功能this.pushToken('DEDENT')
或类似的东西。但是 Jison 文档不是很好,我可以使用一些帮助。
有什么想法吗?
编辑:
在查看生成的解析器代码后,我似乎已经能够解决这个问题。这似乎是可行的......
if (tokens.length) {
var args = arguments;
tokens.slice(1).forEach(function () {
lexer.performAction.apply(this, args);
}.bind(this));
return 'DEDENT';
}
这会诱使词法分析器对堆栈中的每个输入使用完全相同的输入来执行另一个操作DEDENT
,从而允许它添加适当的 dents。但是,感觉很糟糕,我担心可能会出现无法预料的问题。
如果有人对更好的方法有任何想法,我仍然会喜欢它。