mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-19 16:24:51 +00:00
1531 lines
97 KiB
Plaintext
1531 lines
97 KiB
Plaintext
|
/*
|
||
|
* JavaScript parser based on the grammar described in ECMA-262, 5th ed.
|
||
|
* (http://www.ecma-international.org/publications/standards/Ecma-262.htm)
|
||
|
*
|
||
|
* The parser builds a tree representing the parsed JavaScript, composed of
|
||
|
* basic JavaScript values, arrays and objects (basically JSON). It can be
|
||
|
* easily used by various JavaScript processors, transformers, etc.
|
||
|
*
|
||
|
* Intentional deviations from ECMA-262, 5th ed.:
|
||
|
*
|
||
|
* * The specification does not consider |FunctionDeclaration| and
|
||
|
* |FunctionExpression| as statements, but JavaScript implementations do and
|
||
|
* so are we. This syntax is actually used in the wild (e.g. by jQuery).
|
||
|
*
|
||
|
* Limitations:
|
||
|
*
|
||
|
* * Non-BMP characters are completely ignored to avoid surrogate
|
||
|
* pair handling (JavaScript strings in most implementations are AFAIK
|
||
|
* encoded in UTF-16, though this is not required by the specification --
|
||
|
* see ECMA-262, 5th ed., 4.3.16).
|
||
|
*
|
||
|
* * One can create identifiers containing illegal characters using Unicode
|
||
|
* escape sequences. For example, "abcd\u0020efgh" is not a valid
|
||
|
* identifier, but it is accepted by the parser.
|
||
|
*
|
||
|
* * Strict mode is not recognized. That means that within strict mode code,
|
||
|
* "implements", "interface", "let", "package", "private", "protected",
|
||
|
* "public", "static" and "yield" can be used as names. Many other
|
||
|
* restrictions and exceptions from ECMA-262, 5th ed., Annex C are also not
|
||
|
* applied.
|
||
|
*
|
||
|
* * The parser does not handle regular expression literal syntax (basically,
|
||
|
* it treats anything between "/"'s as an opaque character sequence and also
|
||
|
* does not recognize invalid flags properly).
|
||
|
*
|
||
|
* * The parser doesn't report any early errors except syntax errors (see
|
||
|
* ECMA-262, 5th ed., 16).
|
||
|
*
|
||
|
* At least some of these limitations should be fixed sometimes.
|
||
|
*
|
||
|
* Many thanks to inimino (http://inimino.org/~inimino/blog/) for his ES5 PEG
|
||
|
* (http://boshi.inimino.org/3box/asof/1270029991384/PEG/ECMAScript_unified.peg),
|
||
|
* which helped me to solve some problems (such as automatic semicolon
|
||
|
* insertion) and also served to double check that I converted the original
|
||
|
* grammar correctly.
|
||
|
*/
|
||
|
|
||
|
start
|
||
|
= __ program:Program __ { return program; }
|
||
|
|
||
|
/* ===== A.1 Lexical Grammar ===== */
|
||
|
|
||
|
SourceCharacter
|
||
|
= .
|
||
|
|
||
|
WhiteSpace "whitespace"
|
||
|
= [\t\v\f \u00A0\uFEFF]
|
||
|
/ Zs
|
||
|
|
||
|
LineTerminator
|
||
|
= [\n\r\u2028\u2029]
|
||
|
|
||
|
LineTerminatorSequence "end of line"
|
||
|
= "\n"
|
||
|
/ "\r\n"
|
||
|
/ "\r"
|
||
|
/ "\u2028" // line spearator
|
||
|
/ "\u2029" // paragraph separator
|
||
|
|
||
|
Comment "comment"
|
||
|
= MultiLineComment
|
||
|
/ SingleLineComment
|
||
|
|
||
|
MultiLineComment
|
||
|
= "/*" (!"*/" SourceCharacter)* "*/"
|
||
|
|
||
|
MultiLineCommentNoLineTerminator
|
||
|
= "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/"
|
||
|
|
||
|
SingleLineComment
|
||
|
= "//" (!LineTerminator SourceCharacter)*
|
||
|
|
||
|
Identifier "identifier"
|
||
|
= !ReservedWord name:IdentifierName { return name; }
|
||
|
|
||
|
IdentifierName "identifier"
|
||
|
= start:IdentifierStart parts:IdentifierPart* {
|
||
|
return start + parts.join("");
|
||
|
}
|
||
|
|
||
|
IdentifierStart
|
||
|
= UnicodeLetter
|
||
|
/ "$"
|
||
|
/ "_"
|
||
|
/ "\\" sequence:UnicodeEscapeSequence { return sequence; }
|
||
|
|
||
|
IdentifierPart
|
||
|
= IdentifierStart
|
||
|
/ UnicodeCombiningMark
|
||
|
/ UnicodeDigit
|
||
|
/ UnicodeConnectorPunctuation
|
||
|
/ "\u200C" { return "\u200C"; } // zero-width non-joiner
|
||
|
/ "\u200D" { return "\u200D"; } // zero-width joiner
|
||
|
|
||
|
UnicodeLetter
|
||
|
= Lu
|
||
|
/ Ll
|
||
|
/ Lt
|
||
|
/ Lm
|
||
|
/ Lo
|
||
|
/ Nl
|
||
|
|
||
|
UnicodeCombiningMark
|
||
|
= Mn
|
||
|
/ Mc
|
||
|
|
||
|
UnicodeDigit
|
||
|
= Nd
|
||
|
|
||
|
UnicodeConnectorPunctuation
|
||
|
= Pc
|
||
|
|
||
|
ReservedWord
|
||
|
= Keyword
|
||
|
/ FutureReservedWord
|
||
|
/ NullLiteral
|
||
|
/ BooleanLiteral
|
||
|
|
||
|
Keyword
|
||
|
= (
|
||
|
"break"
|
||
|
/ "case"
|
||
|
/ "catch"
|
||
|
/ "continue"
|
||
|
/ "debugger"
|
||
|
/ "default"
|
||
|
/ "delete"
|
||
|
/ "do"
|
||
|
/ "else"
|
||
|
/ "finally"
|
||
|
/ "for"
|
||
|
/ "function"
|
||
|
/ "if"
|
||
|
/ "instanceof"
|
||
|
/ "in"
|
||
|
/ "new"
|
||
|
/ "return"
|
||
|
/ "switch"
|
||
|
/ "this"
|
||
|
/ "throw"
|
||
|
/ "try"
|
||
|
/ "typeof"
|
||
|
/ "var"
|
||
|
/ "void"
|
||
|
/ "while"
|
||
|
/ "with"
|
||
|
)
|
||
|
!IdentifierPart
|
||
|
|
||
|
FutureReservedWord
|
||
|
= (
|
||
|
"class"
|
||
|
/ "const"
|
||
|
/ "enum"
|
||
|
/ "export"
|
||
|
/ "extends"
|
||
|
/ "import"
|
||
|
/ "super"
|
||
|
)
|
||
|
!IdentifierPart
|
||
|
|
||
|
/*
|
||
|
* This rule contains an error in the specification: |RegularExpressionLiteral|
|
||
|
* is missing.
|
||
|
*/
|
||
|
Literal
|
||
|
= NullLiteral
|
||
|
/ BooleanLiteral
|
||
|
/ value:NumericLiteral {
|
||
|
return {
|
||
|
type: "NumericLiteral",
|
||
|
value: value
|
||
|
};
|
||
|
}
|
||
|
/ value:StringLiteral {
|
||
|
return {
|
||
|
type: "StringLiteral",
|
||
|
value: value
|
||
|
};
|
||
|
}
|
||
|
/ RegularExpressionLiteral
|
||
|
|
||
|
NullLiteral
|
||
|
= NullToken { return { type: "NullLiteral" }; }
|
||
|
|
||
|
BooleanLiteral
|
||
|
= TrueToken { return { type: "BooleanLiteral", value: true }; }
|
||
|
/ FalseToken { return { type: "BooleanLiteral", value: false }; }
|
||
|
|
||
|
NumericLiteral "number"
|
||
|
= literal:(HexIntegerLiteral / DecimalLiteral) !IdentifierStart {
|
||
|
return literal;
|
||
|
}
|
||
|
|
||
|
DecimalLiteral
|
||
|
= before:DecimalIntegerLiteral
|
||
|
"."
|
||
|
after:DecimalDigits?
|
||
|
exponent:ExponentPart? {
|
||
|
return parseFloat(before + "." + after + exponent);
|
||
|
}
|
||
|
/ "." after:DecimalDigits exponent:ExponentPart? {
|
||
|
return parseFloat("." + after + exponent);
|
||
|
}
|
||
|
/ before:DecimalIntegerLiteral exponent:ExponentPart? {
|
||
|
return parseFloat(before + exponent);
|
||
|
}
|
||
|
|
||
|
DecimalIntegerLiteral
|
||
|
= "0" / digit:NonZeroDigit digits:DecimalDigits? { return digit + digits; }
|
||
|
|
||
|
DecimalDigits
|
||
|
= digits:DecimalDigit+ { return digits.join(""); }
|
||
|
|
||
|
DecimalDigit
|
||
|
= [0-9]
|
||
|
|
||
|
NonZeroDigit
|
||
|
= [1-9]
|
||
|
|
||
|
ExponentPart
|
||
|
= indicator:ExponentIndicator integer:SignedInteger {
|
||
|
return indicator + integer;
|
||
|
}
|
||
|
|
||
|
ExponentIndicator
|
||
|
= [eE]
|
||
|
|
||
|
SignedInteger
|
||
|
= sign:[-+]? digits:DecimalDigits { return sign + digits; }
|
||
|
|
||
|
HexIntegerLiteral
|
||
|
= "0" [xX] digits:HexDigit+ { return parseInt("0x" + digits.join("")); }
|
||
|
|
||
|
HexDigit
|
||
|
= [0-9a-fA-F]
|
||
|
|
||
|
StringLiteral "string"
|
||
|
= parts:('"' DoubleStringCharacters? '"' / "'" SingleStringCharacters? "'") {
|
||
|
return parts[1];
|
||
|
}
|
||
|
|
||
|
DoubleStringCharacters
|
||
|
= chars:DoubleStringCharacter+ { return chars.join(""); }
|
||
|
|
||
|
SingleStringCharacters
|
||
|
= chars:SingleStringCharacter+ { return chars.join(""); }
|
||
|
|
||
|
DoubleStringCharacter
|
||
|
= !('"' / "\\" / LineTerminator) char_:SourceCharacter { return char_; }
|
||
|
/ "\\" sequence:EscapeSequence { return sequence; }
|
||
|
/ LineContinuation
|
||
|
|
||
|
SingleStringCharacter
|
||
|
= !("'" / "\\" / LineTerminator) char_:SourceCharacter { return char_; }
|
||
|
/ "\\" sequence:EscapeSequence { return sequence; }
|
||
|
/ LineContinuation
|
||
|
|
||
|
LineContinuation
|
||
|
= "\\" sequence:LineTerminatorSequence { return sequence; }
|
||
|
|
||
|
EscapeSequence
|
||
|
= CharacterEscapeSequence
|
||
|
/ "0" !DecimalDigit { return "\0"; }
|
||
|
/ HexEscapeSequence
|
||
|
/ UnicodeEscapeSequence
|
||
|
|
||
|
CharacterEscapeSequence
|
||
|
= SingleEscapeCharacter
|
||
|
/ NonEscapeCharacter
|
||
|
|
||
|
SingleEscapeCharacter
|
||
|
= char_:['"\\bfnrtv] {
|
||
|
return char_
|
||
|
.replace("b", "\b")
|
||
|
.replace("f", "\f")
|
||
|
.replace("n", "\n")
|
||
|
.replace("r", "\r")
|
||
|
.replace("t", "\t")
|
||
|
.replace("v", "\x0B") // IE does not recognize "\v".
|
||
|
}
|
||
|
|
||
|
NonEscapeCharacter
|
||
|
= (!EscapeCharacter / LineTerminator) char_:SourceCharacter { return char_; }
|
||
|
|
||
|
EscapeCharacter
|
||
|
= SingleEscapeCharacter
|
||
|
/ DecimalDigit
|
||
|
/ "x"
|
||
|
/ "u"
|
||
|
|
||
|
HexEscapeSequence
|
||
|
= "x" h1:HexDigit h2:HexDigit {
|
||
|
return String.fromCharCode(parseInt("0x" + h1 + h2));
|
||
|
}
|
||
|
|
||
|
UnicodeEscapeSequence
|
||
|
= "u" h1:HexDigit h2:HexDigit h3:HexDigit h4:HexDigit {
|
||
|
return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
|
||
|
}
|
||
|
|
||
|
RegularExpressionLiteral "regular expression"
|
||
|
= "/" body:RegularExpressionBody "/" flags:RegularExpressionFlags {
|
||
|
return {
|
||
|
type: "RegularExpressionLiteral",
|
||
|
body: body,
|
||
|
flags: flags
|
||
|
};
|
||
|
}
|
||
|
|
||
|
RegularExpressionBody
|
||
|
= char_:RegularExpressionFirstChar chars:RegularExpressionChars {
|
||
|
return char_ + chars;
|
||
|
}
|
||
|
|
||
|
RegularExpressionChars
|
||
|
= chars:RegularExpressionChar* { return chars.join(""); }
|
||
|
|
||
|
RegularExpressionFirstChar
|
||
|
= ![*\\/[] char_:RegularExpressionNonTerminator { return char_; }
|
||
|
/ RegularExpressionBackslashSequence
|
||
|
/ RegularExpressionClass
|
||
|
|
||
|
RegularExpressionChar
|
||
|
= ![\\/[] char_:RegularExpressionNonTerminator { return char_; }
|
||
|
/ RegularExpressionBackslashSequence
|
||
|
/ RegularExpressionClass
|
||
|
|
||
|
/*
|
||
|
* This rule contains an error in the specification: "NonTerminator" instead of
|
||
|
* "RegularExpressionNonTerminator".
|
||
|
*/
|
||
|
RegularExpressionBackslashSequence
|
||
|
= "\\" char_:RegularExpressionNonTerminator { return "\\" + char_; }
|
||
|
|
||
|
RegularExpressionNonTerminator
|
||
|
= !LineTerminator char_:SourceCharacter { return char_; }
|
||
|
|
||
|
RegularExpressionClass
|
||
|
= "[" chars:RegularExpressionClassChars "]" { return "[" + chars + "]"; }
|
||
|
|
||
|
RegularExpressionClassChars
|
||
|
= chars:RegularExpressionClassChar* { return chars.join(""); }
|
||
|
|
||
|
RegularExpressionClassChar
|
||
|
= ![\]\\] char_:RegularExpressionNonTerminator { return char_; }
|
||
|
/ RegularExpressionBackslashSequence
|
||
|
|
||
|
RegularExpressionFlags
|
||
|
= parts:IdentifierPart* { return parts.join(""); }
|
||
|
|
||
|
/* Tokens */
|
||
|
|
||
|
BreakToken = "break" !IdentifierPart
|
||
|
CaseToken = "case" !IdentifierPart
|
||
|
CatchToken = "catch" !IdentifierPart
|
||
|
ContinueToken = "continue" !IdentifierPart
|
||
|
DebuggerToken = "debugger" !IdentifierPart
|
||
|
DefaultToken = "default" !IdentifierPart
|
||
|
DeleteToken = "delete" !IdentifierPart { return "delete"; }
|
||
|
DoToken = "do" !IdentifierPart
|
||
|
ElseToken = "else" !IdentifierPart
|
||
|
FalseToken = "false" !IdentifierPart
|
||
|
FinallyToken = "finally" !IdentifierPart
|
||
|
ForToken = "for" !IdentifierPart
|
||
|
FunctionToken = "function" !IdentifierPart
|
||
|
GetToken = "get" !IdentifierPart
|
||
|
IfToken = "if" !IdentifierPart
|
||
|
InstanceofToken = "instanceof" !IdentifierPart { return "instanceof"; }
|
||
|
InToken = "in" !IdentifierPart { return "in"; }
|
||
|
NewToken = "new" !IdentifierPart
|
||
|
NullToken = "null" !IdentifierPart
|
||
|
ReturnToken = "return" !IdentifierPart
|
||
|
SetToken = "set" !IdentifierPart
|
||
|
SwitchToken = "switch" !IdentifierPart
|
||
|
ThisToken = "this" !IdentifierPart
|
||
|
ThrowToken = "throw" !IdentifierPart
|
||
|
TrueToken = "true" !IdentifierPart
|
||
|
TryToken = "try" !IdentifierPart
|
||
|
TypeofToken = "typeof" !IdentifierPart { return "typeof"; }
|
||
|
VarToken = "var" !IdentifierPart
|
||
|
VoidToken = "void" !IdentifierPart { return "void"; }
|
||
|
WhileToken = "while" !IdentifierPart
|
||
|
WithToken = "with" !IdentifierPart
|
||
|
|
||
|
/*
|
||
|
* Unicode Character Categories
|
||
|
*
|
||
|
* Source: http://www.fileformat.info/info/unicode/category/index.htm
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Non-BMP characters are completely ignored to avoid surrogate pair handling
|
||
|
* (JavaScript strings in most implementations are encoded in UTF-16, though
|
||
|
* this is not required by the specification -- see ECMA-262, 5th ed., 4.3.16).
|
||
|
*
|
||
|
* If you ever need to correctly recognize all the characters, please feel free
|
||
|
* to implement that and send a patch.
|
||
|
*/
|
||
|
|
||
|
// Letter, Lowercase
|
||
|
Ll = [\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007A\u00AA\u00B5\u00BA\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E\u017F\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199\u019A\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD\u01BE\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233\u0234\u0235\u0236\u0237\u0238\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025A\u025B\u025C\u025D\u025E\u025F\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026A\u026B\u026C\u026D\u026E\u026F\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027A\u027B\u027C\u027D\u027E\u027F\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028A\u028B\u028C\u028D\u028E\u028F\u0290\u0291\u0292\u0293\u0295\u0296\u0297\u0298\u0299\u029A\u029B\u029C\u029D\u029E\u029F\u02A0\u02A1\u02A2\u02A3\u02A4\u02A5\u02A6\u02A7\u02A8\u02A9\u02AA\u02AB\u02AC\u02AD\u02AE\u02AF\u0371\u0373\u0377\u037B\u037C\u037D\u0390\u03AC\u03AD\u03AE\u03AF\u03B0\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u03CA\u03CB\u03CC\u03CD\u03CE\u03D0\u03D1\u03D5\u03D6\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF\u03F0\u03F1\u03F2\u03F3\u03F5\u03F8\u03FB\u03FC\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045A\u045B\u045C\u045D\u045E\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056A\u056B\u056C\u056D\u056E\u056F\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057A\u057B\u057C\u057D\u057E\u057F\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587\u1D00\u1D01\u1D02\u1D03\u1D04\u1D05\u1D06\u1D07\u1D08\u1D09\u1D0A\u1D0B\u1D0C\u1D0D\u1D0E\u1D0F\u1D10\u1D11\u1D12\u1D13\u1D14\u1D15\u1D16\u1D17\u1D18\u1D19\u1D1A\u1D1B\u1D1C\u1D1D\u1D1E\u1D1F\u1D20\u1D21\u1D22\u1D23\u1D24\u1D25\u1D26\u1D27\u1D28\u1D29\u1D2A\u1D2B\u1D62\u1D63\u1D64\u1D65\u1D66\u1D67\u1D68\u1D69\u1D6A\u1D6B\u1D6C\u1D6D\u1D6E\u1D6F\u1D70\u1D71\u1D72\u1D73\u1D74\u1D75\u1D76\u1D77\u1D79\u1D7A\u1D7B\u1D7C\u1D7D\u1D7E\u1D7F\u1D80\u1D81\u1D82\u1D83\u1D84\u1D85\u1D86\u1D87\u1D88\u1D89\u1D8A\u1D8B\u1D8C\u1D8D\u1D8E\u1D8F\u1D90\u1D91\u1D92\u1D93\u1D94\u1D95\u1D96\u1D97\u1D98\u1D99\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1
|
||
|
|
||
|
// Letter, Modifier
|
||
|
Lm = [\u02B0\u02B1\u02B2\u02B3\u02B4\u02B5\u02B6\u02B7\u02B8\u02B9\u02BA\u02BB\u02BC\u02BD\u02BE\u02BF\u02C0\u02C1\u02C6\u02C7\u02C8\u02C9\u02CA\u02CB\u02CC\u02CD\u02CE\u02CF\u02D0\u02D1\u02E0\u02E1\u02E2\u02E3\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5\u06E6\u07F4\u07F5\u07FA\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1C78\u1C79\u1C7A\u1C7B\u1C7C\u1C7D\u1D2C\u1D2D\u1D2E\u1D2F\u1D30\u1D31\u1D32\u1D33\u1D34\u1D35\u1D36\u1D37\u1D38\u1D39\u1D3A\u1D3B\u1D3C\u1D3D\u1D3E\u1D3F\u1D40\u1D41\u1D42\u1D43\u1D44\u1D45\u1D46\u1D47\u1D48\u1D49\u1D4A\u1D4B\u1D4C\u1D4D\u1D4E\u1D4F\u1D50\u1D51\u1D52\u1D53\u1D54\u1D55\u1D56\u1D57\u1D58\u1D59\u1D5A\u1D5B\u1D5C\u1D5D\u1D5E\u1D5F\u1D60\u1D61\u1D78\u1D9B\u1D9C\u1D9D\u1D9E\u1D9F\u1DA0\u1DA1\u1DA2\u1DA3\u1DA4\u1DA5\u1DA6\u1DA7\u1DA8\u1DA9\u1DAA\u1DAB\u1DAC\u1DAD\u1DAE\u1DAF\u1DB0\u1DB1\u1DB2\u1DB3\u1DB4\u1DB5\u1DB6\u1DB7\u1DB8\u1DB9\u1DBA\u1DBB\u1DBC\u1DBD\u1DBE\u1DBF\u2090\u2091\u2092\u2093\u2094\u2C7D\u2D6F\u2E2F\u3005\u3031\u3032\u3033\u3034\u3035\u303B\u309D\u309E\u30FC\u30FD\u30FE\uA015\uA60C\uA67F\uA717\uA718\uA719\uA71A\uA71B\uA71C\uA71D\uA71E\uA71F\uA770\uA788\uFF70\uFF9E\uFF9F]
|
||
|
|
||
|
// Letter, Other
|
||
|
Lo = [\u01BB\u01C0\u01C1\u01C2\u01C3\u0294\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5\u05E6\u05E7\u05E8\u05E9\u05EA\u05F0\u05F1\u05F2\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063A\u063B\u063C\u063D\u063E\u063F\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064A\u066E\u066F\u0671\u0672\u0673\u0674\u0675\u0676\u0677\u0678\u0679\u067A\u067B\u067C\u067D\u067E\u067F\u0680\u0681\u0682\u0683\u0684\u0685\u0686\u0687\u0688\u0689\u068A\u068B\u068C\u068D\u068E\u068F\u0690\u0691\u0692\u0693\u0694\u0695\u0696\u0697\u0698\u0699\u069A\u069B\u069C\u069D\u069E\u069F\u06A0\u06A1\u06A2\u06A3\u06A4\u06A5\u06A6\u06A7\u06A8\u06A9\u06AA\u06AB\u06AC\u06AD\u06AE\u06AF\u06B0\u06B1\u06B2\u06B3\u06B4\u06B5\u06B6\u06B7\u06B8\u06B9\u06BA\u06BB\u06BC\u06BD\u06BE\u06BF\u06C0\u06C1\u06C2\u06C3\u06C4\u06C5\u06C6\u06C7\u06C8\u06C9\u06CA\u06CB\u06CC\u06CD\u06CE\u06CF\u06D0\u06D1\u06D2\u06D3\u06D5\u06EE\u06EF\u06FA\u06FB\u06FC\u06FF\u0710\u0712\u0713\u0714\u0715\u0716\u0717\u0718\u0719\u071A\u071B\u071C\u071D\u071E\u071F\u0720\u0721\u0722\u0723\u0724\u0725\u0726\u0727\u0728\u0729\u072A\u072B\u072C\u072D\u072E\u072F\u074D\u074E\u074F\u0750\u0751\u0752\u0753\u0754\u0755\u0756\u0757\u0758\u0759\u075A\u075B\u075C\u075D\u075E\u075F\u0760\u0761\u0762\u0763\u0764\u0765\u0766\u0767\u0768\u0769\u076A\u076B\u076C\u076D\u076E\u076F\u0770\u0771\u0772\u0773\u0774\u0775\u0776\u0777\u0778\u0779\u077A\u077B\u077C\u077D\u077E\u077F\u0780\u0781\u0782\u0783\u0784\u0785\u0786\u0787\u0788\u0789\u078A\u078B\u078C\u078D\u078E\u078F\u0790\u0791\u0792\u0793\u0794\u0795\u0796\u0797\u0798\u0799\u079A\u079B\u079C\u079D\u079E\u079F\u07A0\u07A1\u07A2\u07A3\u07A4\u07A5\u07B1\u07CA\u07CB\u07CC\u07CD\u07CE\u07CF\u07D0\u07D1\u07D2\u07D3\u07D4\u07D5\u07D6\u07D7\u07D8\u07D9\u07DA\u07DB\u07DC\u07DD\u07DE\u07DF\u07E0\u07E1\u07E2\u07E3\u07E4\u07E5\u07E6\u07E7\u07E8\u07E9\u07EA\u0904\u0905\u0906\u0907\u0908\u0909\u090A\u090B\u090C\u090D\u090E\u090F\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091A\u091B\u091C\u091D\u091E\u091F\u0920\u0921\u0922\u0923\u0924\u0925\u0926\u0927\u0928\u0929\u092A\u092B\u092C\u092D\u092E\u092F\u0930\u0931\u0932\u0933\u0934\u0935\u0936\u0937\u0938\u0939\u093D\u0950\u0958\u0959\u095A\u095B\u095C\u095D\u095E\u095F\u0960\u0961\u0972\u097B\u097C\u097D\u097E\u097F\u0985\u0986\u0987\u0988\u0989\u098A\u098B\u098C\u098F\u0990\u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099A\u099B\u099C\u099D\u099E\u099F\u09A0\u09A1\u09A2\u09A3\u09A4\u09A5\u09A6\u09A7\u09A8\u09AA\u09AB\u09AC\u09AD\u09AE\u09AF\u09B0\u09B2\u09B6\u09B7\u09B8\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF\u09E0\u09E1\u09F0\u09F1\u0A05\u0A06\u0A07\u0A08\u0A09\u0A0A\u0A0F\u0A10\u0A13\u0A14\u0A15\u0A16\u0A17\u0A18\u0A19\u0A1A\u0A1B\u0A1C\u0A1D\u0A1E\u0A1F\u0A20\u0A21\u0A22\u0A23\u0A24\u0A25\u0A26\u0A27\u0A28\u0A2A\u0A2B\u0A2C\u0A2D\u0A2E\u0A2F\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59\u0A5A\u0A5B\u0A5C\u0A5E\u0A72\u0A73\u0A74\u0A85\u0A86\u0A87\u0A88\u0A89\u0A8A\u0A8B\u0A8C\u0A8D\u0A8F\u0A90\u0A91\u0A93\u0A94\u0A95\u0A96\u0A97\u0A98\u0A99\u0A9A\u0A9B\u0A9C\u0A9D\u0A9E\u0A9F\u0AA0\u0AA1\u0AA2\u0AA3\u0AA4\u0AA5\u0AA6\u0AA7\u0AA8\u0AAA\u0AAB\u0AAC\u0AAD\u0AAE\u0AAF\u0AB0\u0AB2\u0AB3\u0AB5\u0AB6\u0AB7\u0AB8\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05\u0B06\u0B07\u0B08\u0B09\u0B0A\u0B0B\u0B0C\u0B0F\u0B10\u0B13\u0B14\u0B15\u0B16\u0B17\u0B18\u0B19\u0B1A\u0B1B\u0B1C\u0B1D\u0B1E\u0B1F\u0B20\u0B21\u0B22\u0B23\u0B24\u0B25\u0B26\u0B27\u0B28\u0B2A\u0B2B\u0B2C\u0B2D\u0B2E\u0B2F\u0B30\u0B32\u0B33\u0B35\u0B36\u0B37\u0B38\u0B39\u0B3D\u0B5C\u0B5D\u0B5F\u0B60\u0B61\u0B71\u0B83\u0B85\u0B86\u0B87\u0B88\u0B89\u0B8A\u0B8E\u0B8F\u0B90\u0B92\u0B93\u0B94\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8\u0BA9\u0BAA\u0BAE\u0BAF\u0BB0\u0BB1\u0BB2\u0BB3\u0BB4\u0BB5\u0BB6\u0BB7\u0BB8\u0BB9\u0BD0\u0C05\u0C06\u0C07\u0C08\u0C09\u0C0A\u0C0B\u0C0C\u0C0E\u0C0F\u0C10\u0C12\u0C13\u0C14\u0C15\u0C16\u0C17\u0C18\u0C19\u0C1A\u0C1B\u0C1C\u0C1D\u0C1E\u0
|
||
|
|
||
|
// Letter, Titlecase
|
||
|
Lt = [\u01C5\u01C8\u01CB\u01F2\u1F88\u1F89\u1F8A\u1F8B\u1F8C\u1F8D\u1F8E\u1F8F\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D\u1F9E\u1F9F\u1FA8\u1FA9\u1FAA\u1FAB\u1FAC\u1FAD\u1FAE\u1FAF\u1FBC\u1FCC\u1FFC]
|
||
|
|
||
|
// Letter, Uppercase
|
||
|
Lu = [\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005A\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189\u018A\u018B\u018E\u018F\u0190\u0191\u0193\u0194\u0196\u0197\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1\u01B2\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6\u01F7\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243\u0244\u0245\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u0386\u0388\u0389\u038A\u038C\u038E\u038F\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA\u03AB\u03CF\u03D2\u03D3\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD\u03FE\u03FF\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040A\u040B\u040C\u040D\u040E\u040F\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053A\u053B\u053C\u053D\u053E\u053F\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054A\u054B\u054C\u054D\u054E\u054F\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u10A0\u10A1\u10A2\u10A3\u10A4\u10A5\u10A6\u10A7\u10A8\u10A9\u10AA\u10AB\u10AC\u10AD\u10AE\u10AF\u10B0\u10B1\u10B2\u10B3\u10B4\u10B5\u10B6\u10B7\u10B8\u10B9\u10BA\u10BB\u10BC\u10BD\u10BE\u10BF\u10C0\u10C1\u10C2\u10C3\u10C4\u10C5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08\u1F09\u1F0A\u1F0B\u1F0C\u1F0D\u1F0E\u1F0F\u1F18\u1F19\u1F1A\u1F1B\u1F1C\u1F1D\u1F28\u1F29\u1F2A\u1F2B\u1F2C\u1F2D\u1F2E\u1F2F\u1F38\u1F39\u1F3A\u1F3B\u1F3C\u1F3D\u1F3E\u1F3F\u1F48\u1F49\u1F4A\u1F4B\u1F4C\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68\u1F69\u1F6A\u1F6B\u1F6C\u1F6D\u1F6E\u1F6F\u1FB8\u1FB9\u1FBA\u1FBB\u1FC8\u1FC9\u1FCA\u1FCB\u1FD8\u1FD9\u1
|
||
|
|
||
|
// Mark, Spacing Combining
|
||
|
Mc = [\u0903\u093E\u093F\u0940\u0949\u094A\u094B\u094C\u0982\u0983\u09BE\u09BF\u09C0\u09C7\u09C8\u09CB\u09CC\u09D7\u0A03\u0A3E\u0A3F\u0A40\u0A83\u0ABE\u0ABF\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B3E\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0B57\u0BBE\u0BBF\u0BC1\u0BC2\u0BC6\u0BC7\u0BC8\u0BCA\u0BCB\u0BCC\u0BD7\u0C01\u0C02\u0C03\u0C41\u0C42\u0C43\u0C44\u0C82\u0C83\u0CBE\u0CC0\u0CC1\u0CC2\u0CC3\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0CD5\u0CD6\u0D02\u0D03\u0D3E\u0D3F\u0D40\u0D46\u0D47\u0D48\u0D4A\u0D4B\u0D4C\u0D57\u0D82\u0D83\u0DCF\u0DD0\u0DD1\u0DD8\u0DD9\u0DDA\u0DDB\u0DDC\u0DDD\u0DDE\u0DDF\u0DF2\u0DF3\u0F3E\u0F3F\u0F7F\u102B\u102C\u1031\u1038\u103B\u103C\u1056\u1057\u1062\u1063\u1064\u1067\u1068\u1069\u106A\u106B\u106C\u106D\u1083\u1084\u1087\u1088\u1089\u108A\u108B\u108C\u108F\u17B6\u17BE\u17BF\u17C0\u17C1\u17C2\u17C3\u17C4\u17C5\u17C7\u17C8\u1923\u1924\u1925\u1926\u1929\u192A\u192B\u1930\u1931\u1933\u1934\u1935\u1936\u1937\u1938\u19B0\u19B1\u19B2\u19B3\u19B4\u19B5\u19B6\u19B7\u19B8\u19B9\u19BA\u19BB\u19BC\u19BD\u19BE\u19BF\u19C0\u19C8\u19C9\u1A19\u1A1A\u1A1B\u1B04\u1B35\u1B3B\u1B3D\u1B3E\u1B3F\u1B40\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1C24\u1C25\u1C26\u1C27\u1C28\u1C29\u1C2A\u1C2B\u1C34\u1C35\uA823\uA824\uA827\uA880\uA881\uA8B4\uA8B5\uA8B6\uA8B7\uA8B8\uA8B9\uA8BA\uA8BB\uA8BC\uA8BD\uA8BE\uA8BF\uA8C0\uA8C1\uA8C2\uA8C3\uA952\uA953\uAA2F\uAA30\uAA33\uAA34\uAA4D]
|
||
|
|
||
|
// Mark, Nonspacing
|
||
|
Mn = [\u0300\u0301\u0302\u0303\u0304\u0305\u0306\u0307\u0308\u0309\u030A\u030B\u030C\u030D\u030E\u030F\u0310\u0311\u0312\u0313\u0314\u0315\u0316\u0317\u0318\u0319\u031A\u031B\u031C\u031D\u031E\u031F\u0320\u0321\u0322\u0323\u0324\u0325\u0326\u0327\u0328\u0329\u032A\u032B\u032C\u032D\u032E\u032F\u0330\u0331\u0332\u0333\u0334\u0335\u0336\u0337\u0338\u0339\u033A\u033B\u033C\u033D\u033E\u033F\u0340\u0341\u0342\u0343\u0344\u0345\u0346\u0347\u0348\u0349\u034A\u034B\u034C\u034D\u034E\u034F\u0350\u0351\u0352\u0353\u0354\u0355\u0356\u0357\u0358\u0359\u035A\u035B\u035C\u035D\u035E\u035F\u0360\u0361\u0362\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036A\u036B\u036C\u036D\u036E\u036F\u0483\u0484\u0485\u0486\u0487\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059A\u059B\u059C\u059D\u059E\u059F\u05A0\u05A1\u05A2\u05A3\u05A4\u05A5\u05A6\u05A7\u05A8\u05A9\u05AA\u05AB\u05AC\u05AD\u05AE\u05AF\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610\u0611\u0612\u0613\u0614\u0615\u0616\u0617\u0618\u0619\u061A\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652\u0653\u0654\u0655\u0656\u0657\u0658\u0659\u065A\u065B\u065C\u065D\u065E\u0670\u06D6\u06D7\u06D8\u06D9\u06DA\u06DB\u06DC\u06DF\u06E0\u06E1\u06E2\u06E3\u06E4\u06E7\u06E8\u06EA\u06EB\u06EC\u06ED\u0711\u0730\u0731\u0732\u0733\u0734\u0735\u0736\u0737\u0738\u0739\u073A\u073B\u073C\u073D\u073E\u073F\u0740\u0741\u0742\u0743\u0744\u0745\u0746\u0747\u0748\u0749\u074A\u07A6\u07A7\u07A8\u07A9\u07AA\u07AB\u07AC\u07AD\u07AE\u07AF\u07B0\u07EB\u07EC\u07ED\u07EE\u07EF\u07F0\u07F1\u07F2\u07F3\u0901\u0902\u093C\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u094D\u0951\u0952\u0953\u0954\u0962\u0963\u0981\u09BC\u09C1\u09C2\u09C3\u09C4\u09CD\u09E2\u09E3\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B\u0A4C\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1\u0AC2\u0AC3\u0AC4\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0B01\u0B3C\u0B3F\u0B41\u0B42\u0B43\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0C3E\u0C3F\u0C40\u0C46\u0C47\u0C48\u0C4A\u0C4B\u0C4C\u0C4D\u0C55\u0C56\u0C62\u0C63\u0CBC\u0CBF\u0CC6\u0CCC\u0CCD\u0CE2\u0CE3\u0D41\u0D42\u0D43\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2\u0DD3\u0DD4\u0DD6\u0E31\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0EB1\u0EB4\u0EB5\u0EB6\u0EB7\u0EB8\u0EB9\u0EBB\u0EBC\u0EC8\u0EC9\u0ECA\u0ECB\u0ECC\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71\u0F72\u0F73\u0F74\u0F75\u0F76\u0F77\u0F78\u0F79\u0F7A\u0F7B\u0F7C\u0F7D\u0F7E\u0F80\u0F81\u0F82\u0F83\u0F84\u0F86\u0F87\u0F90\u0F91\u0F92\u0F93\u0F94\u0F95\u0F96\u0F97\u0F99\u0F9A\u0F9B\u0F9C\u0F9D\u0F9E\u0F9F\u0FA0\u0FA1\u0FA2\u0FA3\u0FA4\u0FA5\u0FA6\u0FA7\u0FA8\u0FA9\u0FAA\u0FAB\u0FAC\u0FAD\u0FAE\u0FAF\u0FB0\u0FB1\u0FB2\u0FB3\u0FB4\u0FB5\u0FB6\u0FB7\u0FB8\u0FB9\u0FBA\u0FBB\u0FBC\u0FC6\u102D\u102E\u102F\u1030\u1032\u1033\u1034\u1035\u1036\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E\u105F\u1060\u1071\u1072\u1073\u1074\u1082\u1085\u1086\u108D\u135F\u1712\u1713\u1714\u1732\u1733\u1734\u1752\u1753\u1772\u1773\u17B7\u17B8\u17B9\u17BA\u17BB\u17BC\u17BD\u17C6\u17C9\u17CA\u17CB\u17CC\u17CD\u17CE\u17CF\u17D0\u17D1\u17D2\u17D3\u17DD\u180B\u180C\u180D\u18A9\u1920\u1921\u1922\u1927\u1928\u1932\u1939\u193A\u193B\u1A17\u1A18\u1B00\u1B01\u1B02\u1B03\u1B34\u1B36\u1B37\u1B38\u1B39\u1B3A\u1B3C\u1B42\u1B6B\u1B6C\u1B6D\u1B6E\u1B6F\u1B70\u1B71\u1B72\u1B73\u1B80\u1B81\u1BA2\u1BA3\u1BA4\u1BA5\u1BA8\u1BA9\u1C2C\u1C2D\u1C2E\u1C2F\u1C30\u1C31\u1C32\u1C33\u1C36\u1C37\u1DC0\u1DC1\u1DC2\u1DC3\u1DC4\u1DC5\u1DC6\u1DC7\u1DC8\u1DC9\u1DCA\u1DCB\u1DCC\u1DCD\u1DCE\u1DCF\u1DD0\u1DD1\u1DD2\u1DD3\u1DD4\u1DD5\u1DD6\u1DD7\u1DD8\u1DD9\u1DDA\u1DDB\u1DDC\u1DDD\u1DDE\u1DDF\u1DE0\u1DE1\u1DE2\u1DE3\u1DE4\u1DE5\u1DE6\u1DFE\u1DFF\u20D0\u20D1\u20D2\u20D3\u20D4\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB\u20DC\u20E1\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB\u20EC\u20ED\u20EE\u20EF\u20F0\u2DE0\u2DE1\u2DE2\u2DE3\u2DE4\u2DE5\u2DE6\u2DE7\u2DE8\u2DE9\u2DEA\u2DEB\u2DEC\u2DED\u2DEE\u2DEF\u2DF0\u2DF1\u2DF2\u2DF3\u2DF4\u2DF5\u2DF6\u2DF7\u2DF8\u2DF9\u2DFA\u2DFB\u2DFC\u2DFD\u2DFE\u2DFF\u3
|
||
|
|
||
|
// Number, Decimal Digit
|
||
|
Nd = [\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9\u07C0\u07C1\u07C2\u07C3\u07C4\u07C5\u07C6\u07C7\u07C8\u07C9\u0966\u0967\u0968\u0969\u096A\u096B\u096C\u096D\u096E\u096F\u09E6\u09E7\u09E8\u09E9\u09EA\u09EB\u09EC\u09ED\u09EE\u09EF\u0A66\u0A67\u0A68\u0A69\u0A6A\u0A6B\u0A6C\u0A6D\u0A6E\u0A6F\u0AE6\u0AE7\u0AE8\u0AE9\u0AEA\u0AEB\u0AEC\u0AED\u0AEE\u0AEF\u0B66\u0B67\u0B68\u0B69\u0B6A\u0B6B\u0B6C\u0B6D\u0B6E\u0B6F\u0BE6\u0BE7\u0BE8\u0BE9\u0BEA\u0BEB\u0BEC\u0BED\u0BEE\u0BEF\u0C66\u0C67\u0C68\u0C69\u0C6A\u0C6B\u0C6C\u0C6D\u0C6E\u0C6F\u0CE6\u0CE7\u0CE8\u0CE9\u0CEA\u0CEB\u0CEC\u0CED\u0CEE\u0CEF\u0D66\u0D67\u0D68\u0D69\u0D6A\u0D6B\u0D6C\u0D6D\u0D6E\u0D6F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0ED0\u0ED1\u0ED2\u0ED3\u0ED4\u0ED5\u0ED6\u0ED7\u0ED8\u0ED9\u0F20\u0F21\u0F22\u0F23\u0F24\u0F25\u0F26\u0F27\u0F28\u0F29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1090\u1091\u1092\u1093\u1094\u1095\u1096\u1097\u1098\u1099\u17E0\u17E1\u17E2\u17E3\u17E4\u17E5\u17E6\u17E7\u17E8\u17E9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u1946\u1947\u1948\u1949\u194A\u194B\u194C\u194D\u194E\u194F\u19D0\u19D1\u19D2\u19D3\u19D4\u19D5\u19D6\u19D7\u19D8\u19D9\u1B50\u1B51\u1B52\u1B53\u1B54\u1B55\u1B56\u1B57\u1B58\u1B59\u1BB0\u1BB1\u1BB2\u1BB3\u1BB4\u1BB5\u1BB6\u1BB7\u1BB8\u1BB9\u1C40\u1C41\u1C42\u1C43\u1C44\u1C45\u1C46\u1C47\u1C48\u1C49\u1C50\u1C51\u1C52\u1C53\u1C54\u1C55\u1C56\u1C57\u1C58\u1C59\uA620\uA621\uA622\uA623\uA624\uA625\uA626\uA627\uA628\uA629\uA8D0\uA8D1\uA8D2\uA8D3\uA8D4\uA8D5\uA8D6\uA8D7\uA8D8\uA8D9\uA900\uA901\uA902\uA903\uA904\uA905\uA906\uA907\uA908\uA909\uAA50\uAA51\uAA52\uAA53\uAA54\uAA55\uAA56\uAA57\uAA58\uAA59\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19]
|
||
|
|
||
|
// Number, Letter
|
||
|
Nl = [\u16EE\u16EF\u16F0\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216A\u216B\u216C\u216D\u216E\u216F\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217A\u217B\u217C\u217D\u217E\u217F\u2180\u2181\u2182\u2185\u2186\u2187\u2188\u3007\u3021\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029\u3038\u3039\u303A]
|
||
|
|
||
|
// Punctuation, Connector
|
||
|
Pc = [\u005F\u203F\u2040\u2054\uFE33\uFE34\uFE4D\uFE4E\uFE4F\uFF3F]
|
||
|
|
||
|
// Separator, Space
|
||
|
Zs = [\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000]
|
||
|
|
||
|
/* Automatic Semicolon Insertion */
|
||
|
|
||
|
EOS
|
||
|
= __ ";"
|
||
|
/ _ LineTerminatorSequence
|
||
|
/ _ &"}"
|
||
|
/ __ EOF
|
||
|
|
||
|
EOSNoLineTerminator
|
||
|
= _ ";"
|
||
|
/ _ LineTerminatorSequence
|
||
|
/ _ &"}"
|
||
|
/ _ EOF
|
||
|
|
||
|
EOF
|
||
|
= !.
|
||
|
|
||
|
/* Whitespace */
|
||
|
|
||
|
_
|
||
|
= (WhiteSpace / MultiLineCommentNoLineTerminator / SingleLineComment)*
|
||
|
|
||
|
__
|
||
|
= (WhiteSpace / LineTerminatorSequence / Comment)*
|
||
|
|
||
|
/* ===== A.2 Number Conversions ===== */
|
||
|
|
||
|
/*
|
||
|
* Rules from this section are either unused or merged into previous section of
|
||
|
* the grammar.
|
||
|
*/
|
||
|
|
||
|
/* ===== A.3 Expressions ===== */
|
||
|
|
||
|
PrimaryExpression
|
||
|
= ThisToken { return { type: "This" }; }
|
||
|
/ name:Identifier { return { type: "Variable", name: name }; }
|
||
|
/ Literal
|
||
|
/ ArrayLiteral
|
||
|
/ ObjectLiteral
|
||
|
/ "(" __ expression:Expression __ ")" { return expression; }
|
||
|
|
||
|
ArrayLiteral
|
||
|
= "[" __ elements:ElementList? __ (Elision __)? "]" {
|
||
|
return {
|
||
|
type: "ArrayLiteral",
|
||
|
elements: elements !== "" ? elements : []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
ElementList
|
||
|
= (Elision __)?
|
||
|
head:AssignmentExpression
|
||
|
tail:(__ "," __ Elision? __ AssignmentExpression)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][5]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Elision
|
||
|
= "," (__ ",")*
|
||
|
|
||
|
ObjectLiteral
|
||
|
= "{" __ properties:(PropertyNameAndValueList __ ("," __)?)? "}" {
|
||
|
return {
|
||
|
type: "ObjectLiteral",
|
||
|
properties: properties !== "" ? properties[0] : []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
PropertyNameAndValueList
|
||
|
= head:PropertyAssignment tail:(__ "," __ PropertyAssignment)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][3]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
PropertyAssignment
|
||
|
= name:PropertyName __ ":" __ value:AssignmentExpression {
|
||
|
return {
|
||
|
type: "PropertyAssignment",
|
||
|
name: name,
|
||
|
value: value
|
||
|
};
|
||
|
}
|
||
|
/ GetToken __ name:PropertyName __
|
||
|
"(" __ ")" __
|
||
|
"{" __ body:FunctionBody __ "}" {
|
||
|
return {
|
||
|
type: "GetterDefinition",
|
||
|
name: name,
|
||
|
body: body
|
||
|
};
|
||
|
}
|
||
|
/ SetToken __ name:PropertyName __
|
||
|
"(" __ param:PropertySetParameterList __ ")" __
|
||
|
"{" __ body:FunctionBody __ "}" {
|
||
|
return {
|
||
|
type: "SetterDefinition",
|
||
|
name: name,
|
||
|
param: param,
|
||
|
body: body
|
||
|
};
|
||
|
}
|
||
|
|
||
|
PropertyName
|
||
|
= IdentifierName
|
||
|
/ StringLiteral
|
||
|
/ NumericLiteral
|
||
|
|
||
|
PropertySetParameterList
|
||
|
= Identifier
|
||
|
|
||
|
MemberExpression
|
||
|
= base:(
|
||
|
PrimaryExpression
|
||
|
/ FunctionExpression
|
||
|
/ NewToken __ constructor:MemberExpression __ arguments:Arguments {
|
||
|
return {
|
||
|
type: "NewOperator",
|
||
|
constructor: constructor,
|
||
|
arguments: arguments
|
||
|
};
|
||
|
}
|
||
|
)
|
||
|
accessors:(
|
||
|
__ "[" __ name:Expression __ "]" { return name; }
|
||
|
/ __ "." __ name:IdentifierName { return name; }
|
||
|
)* {
|
||
|
var result = base;
|
||
|
for (var i = 0; i < accessors.length; i++) {
|
||
|
result = {
|
||
|
type: "PropertyAccess",
|
||
|
base: result,
|
||
|
name: accessors[i]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
NewExpression
|
||
|
= MemberExpression
|
||
|
/ NewToken __ constructor:NewExpression {
|
||
|
return {
|
||
|
type: "NewOperator",
|
||
|
constructor: constructor,
|
||
|
arguments: []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
CallExpression
|
||
|
= base:(
|
||
|
name:MemberExpression __ arguments:Arguments {
|
||
|
return {
|
||
|
type: "FunctionCall",
|
||
|
name: name,
|
||
|
arguments: arguments
|
||
|
};
|
||
|
}
|
||
|
)
|
||
|
argumentsOrAccessors:(
|
||
|
__ arguments:Arguments {
|
||
|
return {
|
||
|
type: "FunctionCallArguments",
|
||
|
arguments: arguments
|
||
|
};
|
||
|
}
|
||
|
/ __ "[" __ name:Expression __ "]" {
|
||
|
return {
|
||
|
type: "PropertyAccessProperty",
|
||
|
name: name
|
||
|
};
|
||
|
}
|
||
|
/ __ "." __ name:IdentifierName {
|
||
|
return {
|
||
|
type: "PropertyAccessProperty",
|
||
|
name: name
|
||
|
};
|
||
|
}
|
||
|
)* {
|
||
|
var result = base;
|
||
|
for (var i = 0; i < argumentsOrAccessors.length; i++) {
|
||
|
switch (argumentsOrAccessors[i].type) {
|
||
|
case "FunctionCallArguments":
|
||
|
result = {
|
||
|
type: "FuctionCall",
|
||
|
name: result,
|
||
|
arguments: argumentsOrAccessors[i].arguments
|
||
|
};
|
||
|
break;
|
||
|
case "PropertyAccessProperty":
|
||
|
result = {
|
||
|
type: "PropertyAccess",
|
||
|
base: result,
|
||
|
name: argumentsOrAccessors[i].name
|
||
|
};
|
||
|
break;
|
||
|
default:
|
||
|
throw new Error(
|
||
|
"Invalid expression type: " + argumentsOrAccessors[i].type
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Arguments
|
||
|
= "(" __ arguments:ArgumentList? __ ")" {
|
||
|
return arguments !== "" ? arguments : [];
|
||
|
}
|
||
|
|
||
|
ArgumentList
|
||
|
= head:AssignmentExpression tail:(__ "," __ AssignmentExpression)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][3]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
LeftHandSideExpression
|
||
|
= CallExpression
|
||
|
/ NewExpression
|
||
|
|
||
|
PostfixExpression
|
||
|
= expression:LeftHandSideExpression _ operator:PostfixOperator {
|
||
|
return {
|
||
|
type: "PostfixExpression",
|
||
|
operator: operator,
|
||
|
expression: expression
|
||
|
};
|
||
|
}
|
||
|
/ LeftHandSideExpression
|
||
|
|
||
|
PostfixOperator
|
||
|
= "++"
|
||
|
/ "--"
|
||
|
|
||
|
UnaryExpression
|
||
|
= PostfixExpression
|
||
|
/ operator:UnaryOperator __ expression:UnaryExpression {
|
||
|
return {
|
||
|
type: "UnaryExpression",
|
||
|
operator: operator,
|
||
|
expression: expression
|
||
|
};
|
||
|
}
|
||
|
|
||
|
UnaryOperator
|
||
|
= DeleteToken
|
||
|
/ VoidToken
|
||
|
/ TypeofToken
|
||
|
/ "++"
|
||
|
/ "--"
|
||
|
/ "+"
|
||
|
/ "-"
|
||
|
/ "~"
|
||
|
/ "!"
|
||
|
|
||
|
MultiplicativeExpression
|
||
|
= head:UnaryExpression
|
||
|
tail:(__ MultiplicativeOperator __ UnaryExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
MultiplicativeOperator
|
||
|
= operator:("*" / "/" / "%") !"=" { return operator; }
|
||
|
|
||
|
AdditiveExpression
|
||
|
= head:MultiplicativeExpression
|
||
|
tail:(__ AdditiveOperator __ MultiplicativeExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
AdditiveOperator
|
||
|
= "+" !("+" / "=") { return "+"; }
|
||
|
/ "-" !("-" / "=") { return "-"; }
|
||
|
|
||
|
ShiftExpression
|
||
|
= head:AdditiveExpression
|
||
|
tail:(__ ShiftOperator __ AdditiveExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
ShiftOperator
|
||
|
= "<<"
|
||
|
/ ">>>"
|
||
|
/ ">>"
|
||
|
|
||
|
RelationalExpression
|
||
|
= head:ShiftExpression
|
||
|
tail:(__ RelationalOperator __ ShiftExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
RelationalOperator
|
||
|
= "<="
|
||
|
/ ">="
|
||
|
/ "<"
|
||
|
/ ">"
|
||
|
/ InstanceofToken
|
||
|
/ InToken
|
||
|
|
||
|
RelationalExpressionNoIn
|
||
|
= head:ShiftExpression
|
||
|
tail:(__ RelationalOperatorNoIn __ ShiftExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
RelationalOperatorNoIn
|
||
|
= "<="
|
||
|
/ ">="
|
||
|
/ "<"
|
||
|
/ ">"
|
||
|
/ InstanceofToken
|
||
|
|
||
|
EqualityExpression
|
||
|
= head:RelationalExpression
|
||
|
tail:(__ EqualityOperator __ RelationalExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
EqualityExpressionNoIn
|
||
|
= head:RelationalExpressionNoIn
|
||
|
tail:(__ EqualityOperator __ RelationalExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
EqualityOperator
|
||
|
= "==="
|
||
|
/ "!=="
|
||
|
/ "=="
|
||
|
/ "!="
|
||
|
|
||
|
BitwiseANDExpression
|
||
|
= head:EqualityExpression
|
||
|
tail:(__ BitwiseANDOperator __ EqualityExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BitwiseANDExpressionNoIn
|
||
|
= head:EqualityExpressionNoIn
|
||
|
tail:(__ BitwiseANDOperator __ EqualityExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BitwiseANDOperator
|
||
|
= "&" !("&" / "=") { return "&"; }
|
||
|
|
||
|
BitwiseXORExpression
|
||
|
= head:BitwiseANDExpression
|
||
|
tail:(__ BitwiseXOROperator __ BitwiseANDExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BitwiseXORExpressionNoIn
|
||
|
= head:BitwiseANDExpressionNoIn
|
||
|
tail:(__ BitwiseXOROperator __ BitwiseANDExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BitwiseXOROperator
|
||
|
= "^" !("^" / "=") { return "^"; }
|
||
|
|
||
|
BitwiseORExpression
|
||
|
= head:BitwiseXORExpression
|
||
|
tail:(__ BitwiseOROperator __ BitwiseXORExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BitwiseORExpressionNoIn
|
||
|
= head:BitwiseXORExpressionNoIn
|
||
|
tail:(__ BitwiseOROperator __ BitwiseXORExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BitwiseOROperator
|
||
|
= "|" !("|" / "=") { return "|"; }
|
||
|
|
||
|
LogicalANDExpression
|
||
|
= head:BitwiseORExpression
|
||
|
tail:(__ LogicalANDOperator __ BitwiseORExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
LogicalANDExpressionNoIn
|
||
|
= head:BitwiseORExpressionNoIn
|
||
|
tail:(__ LogicalANDOperator __ BitwiseORExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
LogicalANDOperator
|
||
|
= "&&" !"=" { return "&&"; }
|
||
|
|
||
|
LogicalORExpression
|
||
|
= head:LogicalANDExpression
|
||
|
tail:(__ LogicalOROperator __ LogicalANDExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
LogicalORExpressionNoIn
|
||
|
= head:LogicalANDExpressionNoIn
|
||
|
tail:(__ LogicalOROperator __ LogicalANDExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
LogicalOROperator
|
||
|
= "||" !"=" { return "||"; }
|
||
|
|
||
|
ConditionalExpression
|
||
|
= condition:LogicalORExpression __
|
||
|
"?" __ trueExpression:AssignmentExpression __
|
||
|
":" __ falseExpression:AssignmentExpression {
|
||
|
return {
|
||
|
type: "ConditionalExpression",
|
||
|
condition: condition,
|
||
|
trueExpression: trueExpression,
|
||
|
falseExpression: falseExpression
|
||
|
};
|
||
|
}
|
||
|
/ LogicalORExpression
|
||
|
|
||
|
ConditionalExpressionNoIn
|
||
|
= condition:LogicalORExpressionNoIn __
|
||
|
"?" __ trueExpression:AssignmentExpressionNoIn __
|
||
|
":" __ falseExpression:AssignmentExpressionNoIn {
|
||
|
return {
|
||
|
type: "ConditionalExpression",
|
||
|
condition: condition,
|
||
|
trueExpression: trueExpression,
|
||
|
falseExpression: falseExpression
|
||
|
};
|
||
|
}
|
||
|
/ LogicalORExpressionNoIn
|
||
|
|
||
|
AssignmentExpression
|
||
|
= left:LeftHandSideExpression __
|
||
|
operator:AssignmentOperator __
|
||
|
right:AssignmentExpression {
|
||
|
return {
|
||
|
type: "AssignmentExpression",
|
||
|
operator: operator,
|
||
|
left: left,
|
||
|
right: right
|
||
|
};
|
||
|
}
|
||
|
/ ConditionalExpression
|
||
|
|
||
|
AssignmentExpressionNoIn
|
||
|
= left:LeftHandSideExpression __
|
||
|
operator:AssignmentOperator __
|
||
|
right:AssignmentExpressionNoIn {
|
||
|
return {
|
||
|
type: "AssignmentExpression",
|
||
|
operator: operator,
|
||
|
left: left,
|
||
|
right: right
|
||
|
};
|
||
|
}
|
||
|
/ ConditionalExpressionNoIn
|
||
|
|
||
|
AssignmentOperator
|
||
|
= "=" (!"=") { return "="; }
|
||
|
/ "*="
|
||
|
/ "/="
|
||
|
/ "%="
|
||
|
/ "+="
|
||
|
/ "-="
|
||
|
/ "<<="
|
||
|
/ ">>="
|
||
|
/ ">>>="
|
||
|
/ "&="
|
||
|
/ "^="
|
||
|
/ "|="
|
||
|
|
||
|
Expression
|
||
|
= head:AssignmentExpression
|
||
|
tail:(__ "," __ AssignmentExpression)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
ExpressionNoIn
|
||
|
= head:AssignmentExpressionNoIn
|
||
|
tail:(__ "," __ AssignmentExpressionNoIn)* {
|
||
|
var result = head;
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result = {
|
||
|
type: "BinaryExpression",
|
||
|
operator: tail[i][1],
|
||
|
left: result,
|
||
|
right: tail[i][3]
|
||
|
};
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/* ===== A.4 Statements ===== */
|
||
|
|
||
|
/*
|
||
|
* The specification does not consider |FunctionDeclaration| and
|
||
|
* |FunctionExpression| as statements, but JavaScript implementations do and so
|
||
|
* are we. This syntax is actually used in the wild (e.g. by jQuery).
|
||
|
*/
|
||
|
Statement
|
||
|
= Block
|
||
|
/ VariableStatement
|
||
|
/ EmptyStatement
|
||
|
/ ExpressionStatement
|
||
|
/ IfStatement
|
||
|
/ IterationStatement
|
||
|
/ ContinueStatement
|
||
|
/ BreakStatement
|
||
|
/ ReturnStatement
|
||
|
/ WithStatement
|
||
|
/ LabelledStatement
|
||
|
/ SwitchStatement
|
||
|
/ ThrowStatement
|
||
|
/ TryStatement
|
||
|
/ DebuggerStatement
|
||
|
/ FunctionDeclaration
|
||
|
/ FunctionExpression
|
||
|
|
||
|
Block
|
||
|
= "{" __ statements:(StatementList __)? "}" {
|
||
|
return {
|
||
|
type: "Block",
|
||
|
statements: statements !== "" ? statements[0] : []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
StatementList
|
||
|
= head:Statement tail:(__ Statement)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][1]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
VariableStatement
|
||
|
= VarToken __ declarations:VariableDeclarationList EOS {
|
||
|
return {
|
||
|
type: "VariableStatement",
|
||
|
declarations: declarations
|
||
|
};
|
||
|
}
|
||
|
|
||
|
VariableDeclarationList
|
||
|
= head:VariableDeclaration tail:(__ "," __ VariableDeclaration)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][3]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
VariableDeclarationListNoIn
|
||
|
= head:VariableDeclarationNoIn tail:(__ "," __ VariableDeclarationNoIn)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][3]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
VariableDeclaration
|
||
|
= name:Identifier __ value:Initialiser? {
|
||
|
return {
|
||
|
type: "VariableDeclaration",
|
||
|
name: name,
|
||
|
value: value !== "" ? value : null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
VariableDeclarationNoIn
|
||
|
= name:Identifier __ value:InitialiserNoIn? {
|
||
|
return {
|
||
|
type: "VariableDeclaration",
|
||
|
name: name,
|
||
|
value: value !== "" ? value : null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
Initialiser
|
||
|
= "=" (!"=") __ expression:AssignmentExpression { return expression; }
|
||
|
|
||
|
InitialiserNoIn
|
||
|
= "=" (!"=") __ expression:AssignmentExpressionNoIn { return expression; }
|
||
|
|
||
|
EmptyStatement
|
||
|
= ";" { return { type: "EmptyStatement" }; }
|
||
|
|
||
|
ExpressionStatement
|
||
|
= !("{" / FunctionToken) expression:Expression EOS { return expression; }
|
||
|
|
||
|
IfStatement
|
||
|
= IfToken __
|
||
|
"(" __ condition:Expression __ ")" __
|
||
|
ifStatement:Statement
|
||
|
elseStatement:(__ ElseToken __ Statement)? {
|
||
|
return {
|
||
|
type: "IfStatement",
|
||
|
condition: condition,
|
||
|
ifStatement: ifStatement,
|
||
|
elseStatement: elseStatement !== "" ? elseStatement[3] : null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
IterationStatement
|
||
|
= DoWhileStatement
|
||
|
/ WhileStatement
|
||
|
/ ForStatement
|
||
|
/ ForInStatement
|
||
|
|
||
|
DoWhileStatement
|
||
|
= DoToken __
|
||
|
statement:Statement __
|
||
|
WhileToken __ "(" __ condition:Expression __ ")" EOS {
|
||
|
return {
|
||
|
type: "DoWhileStatement",
|
||
|
condition: condition,
|
||
|
statement: statement
|
||
|
};
|
||
|
}
|
||
|
|
||
|
WhileStatement
|
||
|
= WhileToken __ "(" __ condition:Expression __ ")" __ statement:Statement {
|
||
|
return {
|
||
|
type: "WhileStatement",
|
||
|
condition: condition,
|
||
|
statement: statement
|
||
|
};
|
||
|
}
|
||
|
|
||
|
ForStatement
|
||
|
= ForToken __
|
||
|
"(" __
|
||
|
initializer:(
|
||
|
VarToken __ declarations:VariableDeclarationListNoIn {
|
||
|
return {
|
||
|
type: "VariableStatement",
|
||
|
declarations: declarations
|
||
|
};
|
||
|
}
|
||
|
/ ExpressionNoIn?
|
||
|
) __
|
||
|
";" __
|
||
|
test:Expression? __
|
||
|
";" __
|
||
|
counter:Expression? __
|
||
|
")" __
|
||
|
statement:Statement
|
||
|
{
|
||
|
return {
|
||
|
type: "ForStatement",
|
||
|
initializer: initializer !== "" ? initializer : null,
|
||
|
test: test !== "" ? test : null,
|
||
|
counter: counter !== "" ? counter : null,
|
||
|
statement: statement
|
||
|
};
|
||
|
}
|
||
|
|
||
|
ForInStatement
|
||
|
= ForToken __
|
||
|
"(" __
|
||
|
iterator:(
|
||
|
VarToken __ declaration:VariableDeclarationNoIn { return declaration; }
|
||
|
/ LeftHandSideExpression
|
||
|
) __
|
||
|
InToken __
|
||
|
collection:Expression __
|
||
|
")" __
|
||
|
statement:Statement
|
||
|
{
|
||
|
return {
|
||
|
type: "ForInStatement",
|
||
|
iterator: iterator,
|
||
|
collection: collection,
|
||
|
statement: statement
|
||
|
};
|
||
|
}
|
||
|
|
||
|
ContinueStatement
|
||
|
= ContinueToken _
|
||
|
label:(
|
||
|
identifier:Identifier EOS { return identifier; }
|
||
|
/ EOSNoLineTerminator { return ""; }
|
||
|
) {
|
||
|
return {
|
||
|
type: "ContinueStatement",
|
||
|
label: label !== "" ? label : null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
BreakStatement
|
||
|
= BreakToken _
|
||
|
label:(
|
||
|
identifier:Identifier EOS { return identifier; }
|
||
|
/ EOSNoLineTerminator { return ""; }
|
||
|
) {
|
||
|
return {
|
||
|
type: "BreakStatement",
|
||
|
label: label !== "" ? label : null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
ReturnStatement
|
||
|
= ReturnToken _
|
||
|
value:(
|
||
|
expression:Expression EOS { return expression; }
|
||
|
/ EOSNoLineTerminator { return ""; }
|
||
|
) {
|
||
|
return {
|
||
|
type: "ReturnStatement",
|
||
|
value: value !== "" ? value : null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
WithStatement
|
||
|
= WithToken __ "(" __ environment:Expression __ ")" __ statement:Statement {
|
||
|
return {
|
||
|
type: "WithStatement",
|
||
|
environment: environment,
|
||
|
statement: statement
|
||
|
};
|
||
|
}
|
||
|
|
||
|
SwitchStatement
|
||
|
= SwitchToken __ "(" __ expression:Expression __ ")" __ clauses:CaseBlock {
|
||
|
return {
|
||
|
type: "SwitchStatement",
|
||
|
expression: expression,
|
||
|
clauses: clauses
|
||
|
};
|
||
|
}
|
||
|
|
||
|
CaseBlock
|
||
|
= "{" __
|
||
|
before:CaseClauses?
|
||
|
defaultAndAfter:(__ DefaultClause __ CaseClauses?)? __
|
||
|
"}" {
|
||
|
var before = before !== "" ? before : [];
|
||
|
if (defaultAndAfter !== "") {
|
||
|
var defaultClause = defaultAndAfter[1];
|
||
|
var clausesAfter = defaultAndAfter[3] !== ""
|
||
|
? defaultAndAfter[3]
|
||
|
: [];
|
||
|
} else {
|
||
|
var defaultClause = null;
|
||
|
var clausesAfter = [];
|
||
|
}
|
||
|
|
||
|
return (defaultClause ? before.concat(defaultClause) : before).concat(clausesAfter);
|
||
|
}
|
||
|
|
||
|
CaseClauses
|
||
|
= head:CaseClause tail:(__ CaseClause)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][1]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
CaseClause
|
||
|
= CaseToken __ selector:Expression __ ":" statements:(__ StatementList)? {
|
||
|
return {
|
||
|
type: "CaseClause",
|
||
|
selector: selector,
|
||
|
statements: statements !== "" ? statements[1] : []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
DefaultClause
|
||
|
= DefaultToken __ ":" statements:(__ StatementList)? {
|
||
|
return {
|
||
|
type: "DefaultClause",
|
||
|
statements: statements !== "" ? statements[1] : []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
LabelledStatement
|
||
|
= label:Identifier __ ":" __ statement:Statement {
|
||
|
return {
|
||
|
type: "LabelledStatement",
|
||
|
label: label,
|
||
|
statement: statement
|
||
|
};
|
||
|
}
|
||
|
|
||
|
ThrowStatement
|
||
|
= ThrowToken _ exception:Expression EOSNoLineTerminator {
|
||
|
return {
|
||
|
type: "ThrowStatement",
|
||
|
exception: exception
|
||
|
};
|
||
|
}
|
||
|
|
||
|
TryStatement
|
||
|
= TryToken __ block:Block __ catch_:Catch __ finally_:Finally {
|
||
|
return {
|
||
|
type: "TryStatement",
|
||
|
block: block,
|
||
|
"catch": catch_,
|
||
|
"finally": finally_
|
||
|
};
|
||
|
}
|
||
|
/ TryToken __ block:Block __ catch_:Catch {
|
||
|
return {
|
||
|
type: "TryStatement",
|
||
|
block: block,
|
||
|
"catch": catch_,
|
||
|
"finally": null
|
||
|
};
|
||
|
}
|
||
|
/ TryToken __ block:Block __ finally_:Finally {
|
||
|
return {
|
||
|
type: "TryStatement",
|
||
|
block: block,
|
||
|
"catch": null,
|
||
|
"finally": finally_
|
||
|
};
|
||
|
}
|
||
|
|
||
|
Catch
|
||
|
= CatchToken __ "(" __ identifier:Identifier __ ")" __ block:Block {
|
||
|
return {
|
||
|
type: "Catch",
|
||
|
identifier: identifier,
|
||
|
block: block
|
||
|
};
|
||
|
}
|
||
|
|
||
|
Finally
|
||
|
= FinallyToken __ block:Block {
|
||
|
return {
|
||
|
type: "Finally",
|
||
|
block: block
|
||
|
};
|
||
|
}
|
||
|
|
||
|
DebuggerStatement
|
||
|
= DebuggerToken EOS { return { type: "DebuggerStatement" }; }
|
||
|
|
||
|
/* ===== A.5 Functions and Programs ===== */
|
||
|
|
||
|
FunctionDeclaration
|
||
|
= FunctionToken __ name:Identifier __
|
||
|
"(" __ params:FormalParameterList? __ ")" __
|
||
|
"{" __ elements:FunctionBody __ "}" {
|
||
|
return {
|
||
|
type: "Function",
|
||
|
name: name,
|
||
|
params: params !== "" ? params : [],
|
||
|
elements: elements
|
||
|
};
|
||
|
}
|
||
|
|
||
|
FunctionExpression
|
||
|
= FunctionToken __ name:Identifier? __
|
||
|
"(" __ params:FormalParameterList? __ ")" __
|
||
|
"{" __ elements:FunctionBody __ "}" {
|
||
|
return {
|
||
|
type: "Function",
|
||
|
name: name !== "" ? name : null,
|
||
|
params: params !== "" ? params : [],
|
||
|
elements: elements
|
||
|
};
|
||
|
}
|
||
|
|
||
|
FormalParameterList
|
||
|
= head:Identifier tail:(__ "," __ Identifier)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][3]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
FunctionBody
|
||
|
= elements:SourceElements? { return elements !== "" ? elements : []; }
|
||
|
|
||
|
Program
|
||
|
= elements:SourceElements? {
|
||
|
return {
|
||
|
type: "Program",
|
||
|
elements: elements !== "" ? elements : []
|
||
|
};
|
||
|
}
|
||
|
|
||
|
SourceElements
|
||
|
= head:SourceElement tail:(__ SourceElement)* {
|
||
|
var result = [head];
|
||
|
for (var i = 0; i < tail.length; i++) {
|
||
|
result.push(tail[i][1]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The specification also allows |FunctionDeclaration| here. We do it
|
||
|
* implicitly, because we consider |FunctionDeclaration| and
|
||
|
* |FunctionExpression| as statements. See the coment at the |Statement| rule.
|
||
|
*/
|
||
|
SourceElement
|
||
|
= Statement
|
||
|
|
||
|
/* ===== A.6 Universal Resource Identifier Character Classes ===== */
|
||
|
|
||
|
/* Irrelevant. */
|
||
|
|
||
|
/* ===== A.7 Regular Expressions ===== */
|
||
|
|
||
|
/*
|
||
|
* We treat regular expressions as opaque character sequences and we do not use
|
||
|
* rules from this part of the grammar to parse them further.
|
||
|
*/
|
||
|
|
||
|
/* ===== A.8 JSON ===== */
|
||
|
|
||
|
/* Irrelevant. */
|