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. >
