diff --git a/lib/ometajs/compiler/ir.js b/lib/ometajs/compiler/ir.js index a86a8989..1b1b375b 100644 --- a/lib/ometajs/compiler/ir.js +++ b/lib/ometajs/compiler/ir.js @@ -307,7 +307,12 @@ IR.prototype.render = function render(options) { break; case 'seq': case 're': - buf.push('this._seq(', ast[1], ')'); + if (/^\/\^/.test(ast[1])) { + buf.push('this._seq(', ast[1], ')'); + } else { + var re = ast[1].replace(/^\/(.*)\/(\w*)$/, '/^($1)/$2'); + buf.push('this._seq(', re, ')'); + } break; case 'optional': buf.push('this._', ast[0], '(function() {return '); diff --git a/lib/ometajs/grammars/bsjs.js b/lib/ometajs/grammars/bsjs.js index 763f12a0..a5cc7557 100644 --- a/lib/ometajs/grammars/bsjs.js +++ b/lib/ometajs/grammars/bsjs.js @@ -29,15 +29,15 @@ BSJSParser.prototype["space"] = function $space() { }; BSJSParser.prototype["nameFirst"] = function $nameFirst() { - return this._seq(/^[a-z$_]/i); + return this._seq(/^([a-z$_])/i); }; BSJSParser.prototype["nameLast"] = function $nameLast() { - return this._seq(/^[a-z0-9$_]/i); + return this._seq(/^([a-z0-9$_])/i); }; BSJSParser.prototype["iName"] = function $iName() { - return this._seq(/^[a-z$_][a-z0-9$_]*/i); + return this._seq(/^([a-z$_][a-z0-9$_]*)/i); }; BSJSParser.prototype["isKeyword"] = function $isKeyword() { @@ -74,10 +74,10 @@ BSJSParser.prototype["hexLit"] = function $hexLit() { BSJSParser.prototype["number"] = function $number() { return this._atomic(function() { var n; - return this._seq(/^0x[0-9a-f]+/) && (n = this._getIntermediate(), true) && this._exec([ "number", parseInt(n) ]); + return this._seq(/^(0x[0-9a-f]+)/) && (n = this._getIntermediate(), true) && this._exec([ "number", parseInt(n) ]); }) || this._atomic(function() { var f; - return this._seq(/^\d+((\.|[eE][\-+]?)\d+)?/) && (f = this._getIntermediate(), true) && this._exec([ "number", parseFloat(f) ]); + return this._seq(/^(\d+((\.|[eE][\-+]?)\d+)?)/) && (f = this._getIntermediate(), true) && this._exec([ "number", parseFloat(f) ]); }); }; @@ -125,7 +125,7 @@ BSJSParser.prototype["escapeChar"] = function $escapeChar() { BSJSParser.prototype["str"] = function $str() { return this._atomic(function() { var s; - return this._seq(/^'([^'\\]|\\.)*'/) && (s = this._getIntermediate(), true) && this._exec(function() { + return this._seq(/^('([^'\\]|\\.)*')/) && (s = this._getIntermediate(), true) && this._exec(function() { function swap(quote) { return quote === '"' ? "'" : '"'; } @@ -133,13 +133,13 @@ BSJSParser.prototype["str"] = function $str() { }.call(this)); }) || this._atomic(function() { var s; - return this._seq(/^"([^"\\]|\\.)*"/) && (s = this._getIntermediate(), true) && this._exec([ "string", JSON.parse(preparseString(s)) ]); + return this._seq(/^("([^"\\]|\\.)*")/) && (s = this._getIntermediate(), true) && this._exec([ "string", JSON.parse(preparseString(s)) ]); }); }; BSJSParser.prototype["special"] = function $special() { var s; - return this._seq(/^(>>>|<<<|!==|===|&&=|\|\|=|!=|==|>=|<=|\+\+|\+=|--|-=|\*=|\/=|%=|&&|\|\||>>|&=|\|=|\^=|[\(\){}\[\],;?:><=\+\-\*\/%&|\^~\.!])/) && (s = this._getIntermediate(), true) && this._exec([ s, s ]); + return this._seq(/^((>>>|<<<|!==|===|&&=|\|\|=|!=|==|>=|<=|\+\+|\+=|--|-=|\*=|\/=|%=|&&|\|\||>>|&=|\|=|\^=|[\(\){}\[\],;?:><=\+\-\*\/%&|\^~\.!]))/) && (s = this._getIntermediate(), true) && this._exec([ s, s ]); }; BSJSParser.prototype["token"] = function $token() { diff --git a/lib/ometajs/grammars/bsjs.ometajs b/lib/ometajs/grammars/bsjs.ometajs index dc24487f..ecb65642 100644 --- a/lib/ometajs/grammars/bsjs.ometajs +++ b/lib/ometajs/grammars/bsjs.ometajs @@ -1,16 +1,16 @@ ometa BSJSParser { space = ^@space | /^\/\/[^\n]*/ | /^\/\*(.|[\r\n])*?\*\//, - nameFirst = /^[a-z$_]/i, - nameLast = /^[a-z0-9$_]/i, - iName = /^[a-z$_][a-z0-9$_]*/i, + nameFirst = /[a-z$_]/i, + nameLast = /[a-z0-9$_]/i, + iName = /[a-z$_][a-z0-9$_]*/i, isKeyword :x = ?BSJSParser._isKeyword(x), name = @iName:n ~isKeyword(n) -> [#name, n], keyword = @iName:k isKeyword(k) -> [k, k], hexDigit = @char:x {BSJSParser.hexDigits.indexOf(x.toLowerCase())}:v ?(v >= 0) -> v, hexLit = hexLit:n hexDigit:d -> (n * 16 + d) | hexDigit, - number = /^0x[0-9a-f]+/:n -> [#number, parseInt(n)] - | /^\d+((\.|[eE][\-+]?)\d+)?/:f -> [#number, parseFloat(f)], + number = /0x[0-9a-f]+/:n -> [#number, parseInt(n)] + | /\d+((\.|[eE][\-+]?)\d+)?/:f -> [#number, parseFloat(f)], escapeChar = <'\\' char>:s -> { switch (s) { case '\\"': return '"'; @@ -28,7 +28,7 @@ ometa BSJSParser { | 'x' hexDigit hexDigit)>:s -> { JSON.parse('"' + s + '"') }, - str = /^'([^'\\]|\\.)*'/:s -> { + str = /'([^'\\]|\\.)*'/:s -> { function swap(quote) { return quote === '"' ? '\'' : '"'; } @@ -38,8 +38,8 @@ ometa BSJSParser { .replace(/["']/g, swap) ]; } - | /^"([^"\\]|\\.)*"/:s -> [#string, JSON.parse(preparseString(s))], - special = /^(>>>|<<<|!==|===|&&=|\|\|=|!=|==|>=|<=|\+\+|\+=|--|-=|\*=|\/=|%=|&&|\|\||>>|&=|\|=|\^=|[\(\){}\[\],;?:><=\+\-\*\/%&|\^~\.!])/:s -> [s, s], + | /"([^"\\]|\\.)*"/:s -> [#string, JSON.parse(preparseString(s))], + special = /(>>>|<<<|!==|===|&&=|\|\|=|!=|==|>=|<=|\+\+|\+=|--|-=|\*=|\/=|%=|&&|\|\||>>|&=|\|=|\^=|[\(\){}\[\],;?:><=\+\-\*\/%&|\^~\.!])/:s -> [s, s], token = @spaces (@name | @keyword | @number | @str | @special), toks = @token*:ts @spaces end -> ts, spacesNoNl = (~'\n' space)*,