seems reasonable to me.

On Tue, Jun 14, 2011 at 16:37, Mike Samuel <[email protected]> wrote:
> We have a very good regular lexical grammar that approximates the way
> JavaScript interpreters tokenize JavaScript source, but we rely on our
> source tree rendering to make sure that a JavaScript interpreter will
> always come to the same conclusion as to where regular expression
> literals and division operators start and end.
>
> SES might benefit from a cheap reliable transformation that
> (1) takes a string of SES source
> (2) produces a string of SES source where a standards compliant
>   JavaScript interpreter will either throw a ParseError or come to the
>   same conclusion as an approximate regular lexical grammar
>
> I think the below is such a transformation.
>
> function removeSlashAmbiguity(tokens /* []string */) {
>  var outputTokens = [];
>  for (var i = 0, n = tokens.length; i < n; ++i) {
>    var token = tokens[i];
>    if (isRegularExpressionToken(token)) {
>      outputTokens.push("/./", ".", "constructor", "(", token, ")");
>    } else if (token === "/" || token === "/=") {
>      outputTokens.push(token.replace(/^\//, "*"), "1", "*");
>    } else {
>      outputTokens.push(token);
>    }
>  }
>  return outputTokens;
> }
>
>
> To break it down:
>
> (1) a regular expression /foo/i is transformed to
>    /./.constructor(/foo/i)
>
>    If the "/" at the start of /foo/i were a division operator, then
>    the transformed code would fail to parse because of the dot in
>    /./.
>
>    This is valid because the dot operator and the function call
>    operator bind very tightly.
>
>     It is semantics preserving because /./.constructor is a reliably
>     path (in SES) to RegExp and RegExp(/./) returns its input
>     unchanged.
>
>     It also does not conflict with semicolon insertion -- there is no
>     infix operator on the left (or ParseError would have been thrown)
>     that might attach to the previous line.
>
> (2) A use of the division operator (a / b) is transformed to (a * 1 / b)
>
>     If our lexing was wrong and the slash was the start of a regular
>     expression, then replacing the slash with an asterisk makes the
>     content obviously a numeric operation, so our interpretation is
>     maintained.
>
>     This is semantics preserving because both * and / coerce both
>     sides to numbers, and have the same precedence, and 1 is
>     multiplicative identity.
>
> (3) A use of the /= operator (a /= b) is transformed to (a *= 1 / b)
>
>    Same argument as 2.
>
>    This is semantics preserving because the left-hand side is
>    unchanged and is evaluated only once, and same argument as 2.
>

Reply via email to