JsLex不正确地使用了什么Javascript构造?

JsLex不正确地使用了什么Javascript构造?,javascript,python,tokenize,lexical-analysis,Javascript,Python,Tokenize,Lexical Analysis,是我用Python编写的Javascript lexer。这对一天的工作(大约)来说是一件好事,但我相信在某些情况下它会出错。特别是,它对分号插入没有任何了解,可能有一些方法对词法分析很重要。我只是不知道它们是什么 什么Javascript代码不正确?我特别感兴趣的是JsLex错误地识别正则表达式文本的有效Javascript源代码 需要明确的是,“词法分析”指的是在源文件中识别标记。JsLex不尝试解析Javascript,更不用说执行它了。我已经编写了JsLex来进行完整的词法分析,不过老实

是我用Python编写的Javascript lexer。这对一天的工作(大约)来说是一件好事,但我相信在某些情况下它会出错。特别是,它对分号插入没有任何了解,可能有一些方法对词法分析很重要。我只是不知道它们是什么

什么Javascript代码不正确?我特别感兴趣的是JsLex错误地识别正则表达式文本的有效Javascript源代码


需要明确的是,“词法分析”指的是在源文件中识别标记。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;