JsLex不正确地使用了什么Javascript构造?
是我用Python编写的Javascript lexer。这对一天的工作(大约)来说是一件好事,但我相信在某些情况下它会出错。特别是,它对分号插入没有任何了解,可能有一些方法对词法分析很重要。我只是不知道它们是什么 什么Javascript代码不正确?我特别感兴趣的是JsLex错误地识别正则表达式文本的有效Javascript源代码JsLex不正确地使用了什么Javascript构造?,javascript,python,tokenize,lexical-analysis,Javascript,Python,Tokenize,Lexical Analysis,是我用Python编写的Javascript lexer。这对一天的工作(大约)来说是一件好事,但我相信在某些情况下它会出错。特别是,它对分号插入没有任何了解,可能有一些方法对词法分析很重要。我只是不知道它们是什么 什么Javascript代码不正确?我特别感兴趣的是JsLex错误地识别正则表达式文本的有效Javascript源代码 需要明确的是,“词法分析”指的是在源文件中识别标记。JsLex不尝试解析Javascript,更不用说执行它了。我已经编写了JsLex来进行完整的词法分析,不过老实
需要明确的是,“词法分析”指的是在源文件中识别标记。JsLex不尝试解析Javascript,更不用说执行它了。我已经编写了JsLex来进行完整的词法分析,不过老实说,如果它能够成功地找到所有正则表达式文字,我会很高兴的。它是否能正确地用于此代码(这不应该有分号;正确的词法分析会产生错误) 如果是这样,那么对于依赖于分号插入的代码,它是否正常工作
function square(num) {
var f = function (x) {
return x * x;
}
return f(num);
}
有趣的是,我在我用JS编写的lexer/evaluator代码中尝试了你的lexer;)你说得对,正则表达式并不总是很好。这里有一些例子:
rexl.re = {
NAME: /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/,
UNQUOTED_LITERAL: /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/,
QUOTED_LITERAL: /^'(?:[^']|'')*'/,
NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/,
SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/
};
现在,在名称的
regexp出错之后。它是一根大绳子。我认为后一个问题是字符串标记太贪婪了。对于regex
令牌,前者可能太聪明了
Edit:我想我已经修复了regex
标记的regexp。在代码中,将第146-153行(整个“以下字符”部分)替换为以下表达式:
([^/]|(?<!\\)(?<=\\)/)*
编辑:另一种情况。它似乎对关键词也太贪婪了。见案例:
var clazz = function() {
if (clazz.__) return delete(clazz.__);
this.constructor = clazz;
if(constructor)
constructor.apply(this, arguments);
};
它的词法是:
(关键字,const),(id,构造函数)
。标识符继承
:在
和herits
中也会发生同样的情况 示例:下面第一次出现的/2/i
(对a
的赋值)应标记为Div、NumericLiteral、Div、Identifier,因为它位于InputElementDiv上下文中。第二次出现(对b
的赋值)应标记为RegularExpressionLiteral,因为它位于InputElementRegExp上下文中
资料来源:
词汇语法有两个目标符号。InputElementDiv符号用于允许除法(/
)或除法赋值(/=
)运算符的语法上下文中。InputElementRegExp符号用于其他语法上下文
注意,句法语法中存在上下文,句法语法同时允许除法和正则表达式文字;但是,由于词汇语法在这种情况下使用InputElementDiv目标符号,因此在这种上下文中,开头斜杠不能识别为正则表达式文字的起始。作为一种解决方法,可以将正则表达式文字括在括号中。
-标准ECMA-262第3版-1999年12月,第。十一,
您处理这个棘手问题的解决方案非常简单,但我注意到它不能完全处理ES5的
something.property
语法中的更改,它允许在
之后保留字。即,a.if='foo';(函数(){a.if/=3;})代码>,是中的有效语句
除非我弄错了,
对于属性只有一种用法,所以修复方法可能是在
之后添加一个额外的状态,该状态只接受identifierName标记(identifier使用该标记,但它不拒绝保留字),这可能会起作用。(很明显,div的状态和往常一样。)我一直在思考为JavaScript编写lexer的问题,我在寻找好的技术时遇到了您的实现。我发现了一个你的不起作用的案例,如果你仍然感兴趣,我想与你分享:
var g = 3, x = { valueOf: function() { return 6;} } /2/g;
斜杠和斜杠都应解析为除法运算符,从而将x指定为数值1。你的lexer认为它是一个regexp。如果不维护一堆分组上下文来区分块的结尾(除regexp外),函数语句的结尾(除regexp外),函数表达式的结尾(除除法外),就无法正确处理这种情况下的所有变体,以及对象文本的结尾(除除法外)。它对这段代码来说确实很好,因为它所做的只是识别标记。我最关心的是查找正则表达式文本(我更新了问题以澄清这一点)。我不清楚第一个示例是否应该是语法正确的示例。@Zach:correct syntax;但代码不正确。函数因类型错误而失败,因为它表示var f=function(x){return x*x}(result=f(num))代码>因此在设置f之前应用它。@ThiefMaster:在声明“非常简单”之前,您可能需要进行更多的调查。例如,如何确定/不是部门的一部分?斜杠也可以出现在正则表达式中,比如/[/]/
@ThiefMaster:它实际上非常复杂。除非你密切关注细节,否则它们可能看起来像分裂。分区:a/(b+c/d+e)/g
,正则表达式:/(b+c/d+e)/g
@configurator,是的,它可以很好地解析它们。感谢这些案例,它们帮助我发现了正则表达式与正则表达式匹配的问题。我没有采纳你的解决方案,而是在脑海中删除了一个愚蠢的错误:注释末尾的反斜杠将行连接在一起,注释掉了正则表达式中字符类中转义的识别。谢谢,我已经将这些案例添加到测试套件中。关于关键词的观点很好。我现在也把它修好了。让他们来@Ned最新的代码非常好用。我已经测试了几个相当大和
case 'UNQUOTED_LITERAL':
case 'QUOTED_LITERAL': {
this._js = "e.str(\"" + this.value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\")";
break;
}
var clazz = function() {
if (clazz.__) return delete(clazz.__);
this.constructor = clazz;
if(constructor)
constructor.apply(this, arguments);
};
i = 1;
var a = 1 / 2 /i;
console.info(a); // ⇒ 0.5
console.info(typeof a); // number
var b = 1 + / 2 /i;
console.info(b); // ⇒ 1/2/i
console.info(typeof b); // ⇒ string
var g = 3, x = { valueOf: function() { return 6;} } /2/g;