token.js 129 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022
  1. /*
  2. Copyright (C) 2013 Thaddee Tyl <[email protected]>
  3. Copyright (C) 2012 Ariya Hidayat <[email protected]>
  4. Copyright (C) 2012 Mathias Bynens <[email protected]>
  5. Copyright (C) 2012 Joost-Wim Boekesteijn <[email protected]>
  6. Copyright (C) 2012 Kris Kowal <[email protected]>
  7. Copyright (C) 2012 Yusuke Suzuki <[email protected]>
  8. Copyright (C) 2012 Arpad Borsos <[email protected]>
  9. Copyright (C) 2011 Ariya Hidayat <[email protected]>
  10. Redistribution and use in source and binary forms, with or without
  11. modification, are permitted provided that the following conditions are met:
  12. * Redistributions of source code must retain the above copyright
  13. notice, this list of conditions and the following disclaimer.
  14. * Redistributions in binary form must reproduce the above copyright
  15. notice, this list of conditions and the following disclaimer in the
  16. documentation and/or other materials provided with the distribution.
  17. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  21. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. void function (root, factory) {
  29. factory( root.esprima = root.document.esprima = {} );
  30. }(this, function (exports) {
  31. 'use strict';
  32. var Token,
  33. TokenName,
  34. FnExprTokens,
  35. Syntax,
  36. PropertyKind,
  37. Messages,
  38. Regex,
  39. SyntaxTreeDelegate,
  40. source,
  41. strict,
  42. index,
  43. lineNumber,
  44. lineStart,
  45. length,
  46. delegate,
  47. lookahead,
  48. state,
  49. extra;
  50. Token = {
  51. BooleanLiteral: 1,
  52. EOF: 2,
  53. Identifier: 3,
  54. Keyword: 4,
  55. NullLiteral: 5,
  56. NumericLiteral: 6,
  57. Punctuator: 7,
  58. StringLiteral: 8,
  59. RegularExpression: 9
  60. };
  61. TokenName = {};
  62. TokenName[Token.BooleanLiteral] = 'Boolean';
  63. TokenName[Token.EOF] = '<end>';
  64. TokenName[Token.Identifier] = 'Identifier';
  65. TokenName[Token.Keyword] = 'Keyword';
  66. TokenName[Token.NullLiteral] = 'Null';
  67. TokenName[Token.NumericLiteral] = 'Numeric';
  68. TokenName[Token.Punctuator] = 'Punctuator';
  69. TokenName[Token.StringLiteral] = 'String';
  70. TokenName[Token.RegularExpression] = 'RegularExpression';
  71. // A function following one of those tokens is an expression.
  72. FnExprTokens = ["(", "{", "[", "in", "typeof", "instanceof", "new",
  73. "return", "case", "delete", "throw", "void",
  74. // assignment operators
  75. "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
  76. "&=", "|=", "^=", ",",
  77. // binary/unary operators
  78. "+", "-", "*", "/", "%", "++", "--", "<<", ">>", ">>>", "&",
  79. "|", "^", "!", "~", "&&", "||", "?", ":", "===", "==", ">=",
  80. "<=", "<", ">", "!=", "!=="];
  81. Syntax = {
  82. AssignmentExpression: 'AssignmentExpression',
  83. ArrayExpression: 'ArrayExpression',
  84. BlockStatement: 'BlockStatement',
  85. BinaryExpression: 'BinaryExpression',
  86. BreakStatement: 'BreakStatement',
  87. CallExpression: 'CallExpression',
  88. CatchClause: 'CatchClause',
  89. ConditionalExpression: 'ConditionalExpression',
  90. ContinueStatement: 'ContinueStatement',
  91. DoWhileStatement: 'DoWhileStatement',
  92. DebuggerStatement: 'DebuggerStatement',
  93. EmptyStatement: 'EmptyStatement',
  94. ExpressionStatement: 'ExpressionStatement',
  95. ForStatement: 'ForStatement',
  96. ForInStatement: 'ForInStatement',
  97. FunctionDeclaration: 'FunctionDeclaration',
  98. FunctionExpression: 'FunctionExpression',
  99. Identifier: 'Identifier',
  100. IfStatement: 'IfStatement',
  101. Literal: 'Literal',
  102. LabeledStatement: 'LabeledStatement',
  103. LogicalExpression: 'LogicalExpression',
  104. MemberExpression: 'MemberExpression',
  105. NewExpression: 'NewExpression',
  106. ObjectExpression: 'ObjectExpression',
  107. Program: 'Program',
  108. Property: 'Property',
  109. ReturnStatement: 'ReturnStatement',
  110. SequenceExpression: 'SequenceExpression',
  111. SwitchStatement: 'SwitchStatement',
  112. SwitchCase: 'SwitchCase',
  113. ThisExpression: 'ThisExpression',
  114. ThrowStatement: 'ThrowStatement',
  115. TryStatement: 'TryStatement',
  116. UnaryExpression: 'UnaryExpression',
  117. UpdateExpression: 'UpdateExpression',
  118. VariableDeclaration: 'VariableDeclaration',
  119. VariableDeclarator: 'VariableDeclarator',
  120. WhileStatement: 'WhileStatement',
  121. WithStatement: 'WithStatement'
  122. };
  123. PropertyKind = {
  124. Data: 1,
  125. Get: 2,
  126. Set: 4
  127. };
  128. // Error messages should be identical to V8.
  129. Messages = {
  130. UnexpectedToken: 'Unexpected token %0',
  131. UnexpectedNumber: 'Unexpected number',
  132. UnexpectedString: 'Unexpected string',
  133. UnexpectedIdentifier: 'Unexpected identifier',
  134. UnexpectedReserved: 'Unexpected reserved word',
  135. UnexpectedEOS: 'Unexpected end of input',
  136. NewlineAfterThrow: 'Illegal newline after throw',
  137. InvalidRegExp: 'Invalid regular expression',
  138. UnterminatedRegExp: 'Invalid regular expression: missing /',
  139. InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
  140. InvalidLHSInForIn: 'Invalid left-hand side in for-in',
  141. MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
  142. NoCatchOrFinally: 'Missing catch or finally after try',
  143. UnknownLabel: 'Undefined label \'%0\'',
  144. Redeclaration: '%0 \'%1\' has already been declared',
  145. IllegalContinue: 'Illegal continue statement',
  146. IllegalBreak: 'Illegal break statement',
  147. IllegalReturn: 'Illegal return statement',
  148. StrictModeWith: 'Strict mode code may not include a with statement',
  149. StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
  150. StrictVarName: 'Variable name may not be eval or arguments in strict mode',
  151. StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
  152. StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
  153. StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
  154. StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
  155. StrictDelete: 'Delete of an unqualified identifier in strict mode.',
  156. StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
  157. AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
  158. AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
  159. StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
  160. StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
  161. StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
  162. StrictReservedWord: 'Use of future reserved word in strict mode'
  163. };
  164. // See also tools/generate-unicode-regex.py.
  165. Regex = {
  166. NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'),
  167. NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]')
  168. };
  169. // Ensure the condition is true, otherwise throw an error.
  170. // This is only to have a better contract semantic, i.e. another safety net
  171. // to catch a logic error. The condition shall be fulfilled in normal case.
  172. // Do NOT use this to enforce a certain condition on any user input.
  173. function assert(condition, message) {
  174. if (!condition) {
  175. throw new Error('ASSERT: ' + message);
  176. }
  177. }
  178. function isDecimalDigit(ch) {
  179. return (ch >= 48 && ch <= 57); // 0..9
  180. }
  181. function isHexDigit(ch) {
  182. return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
  183. }
  184. function isOctalDigit(ch) {
  185. return '01234567'.indexOf(ch) >= 0;
  186. }
  187. // 7.2 White Space
  188. function isWhiteSpace(ch) {
  189. return (ch === 32) || // space
  190. (ch === 9) || // tab
  191. (ch === 0xB) ||
  192. (ch === 0xC) ||
  193. (ch === 0xA0) ||
  194. (ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(String.fromCharCode(ch)) > 0);
  195. }
  196. // 7.3 Line Terminators
  197. function isLineTerminator(ch) {
  198. return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029);
  199. }
  200. // 7.6 Identifier Names and Identifiers
  201. function isIdentifierStart(ch) {
  202. return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
  203. (ch >= 65 && ch <= 90) || // A..Z
  204. (ch >= 97 && ch <= 122) || // a..z
  205. (ch === 92) || // \ (backslash)
  206. ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
  207. }
  208. function isIdentifierPart(ch) {
  209. return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
  210. (ch >= 65 && ch <= 90) || // A..Z
  211. (ch >= 97 && ch <= 122) || // a..z
  212. (ch >= 48 && ch <= 57) || // 0..9
  213. (ch === 92) || // \ (backslash)
  214. ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
  215. }
  216. // 7.6.1.2 Future Reserved Words
  217. function isFutureReservedWord(id) {
  218. switch (id) {
  219. case 'class':
  220. case 'enum':
  221. case 'export':
  222. case 'extends':
  223. case 'import':
  224. case 'super':
  225. return true;
  226. default:
  227. return false;
  228. }
  229. }
  230. function isStrictModeReservedWord(id) {
  231. switch (id) {
  232. case 'implements':
  233. case 'interface':
  234. case 'package':
  235. case 'private':
  236. case 'protected':
  237. case 'public':
  238. case 'static':
  239. case 'yield':
  240. case 'let':
  241. return true;
  242. default:
  243. return false;
  244. }
  245. }
  246. function isRestrictedWord(id) {
  247. return id === 'eval' || id === 'arguments';
  248. }
  249. // 7.6.1.1 Keywords
  250. function isKeyword(id) {
  251. if (strict && isStrictModeReservedWord(id)) {
  252. return true;
  253. }
  254. // 'const' is specialized as Keyword in V8.
  255. // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
  256. // Some others are from future reserved words.
  257. switch (id.length) {
  258. case 2:
  259. return (id === 'if') || (id === 'in') || (id === 'do');
  260. case 3:
  261. return (id === 'var') || (id === 'for') || (id === 'new') ||
  262. (id === 'try') || (id === 'let');
  263. case 4:
  264. return (id === 'this') || (id === 'else') || (id === 'case') ||
  265. (id === 'void') || (id === 'with') || (id === 'enum');
  266. case 5:
  267. return (id === 'while') || (id === 'break') || (id === 'catch') ||
  268. (id === 'throw') || (id === 'const') || (id === 'yield') ||
  269. (id === 'class') || (id === 'super');
  270. case 6:
  271. return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
  272. (id === 'switch') || (id === 'export') || (id === 'import');
  273. case 7:
  274. return (id === 'default') || (id === 'finally') || (id === 'extends');
  275. case 8:
  276. return (id === 'function') || (id === 'continue') || (id === 'debugger');
  277. case 10:
  278. return (id === 'instanceof');
  279. default:
  280. return false;
  281. }
  282. }
  283. // 7.4 Comments
  284. function skipComment() {
  285. var ch, blockComment, lineComment;
  286. blockComment = false;
  287. lineComment = false;
  288. while (index < length) {
  289. ch = source.charCodeAt(index);
  290. if (lineComment) {
  291. ++index;
  292. if (isLineTerminator(ch)) {
  293. lineComment = false;
  294. if (ch === 13 && source.charCodeAt(index) === 10) {
  295. ++index;
  296. }
  297. ++lineNumber;
  298. lineStart = index;
  299. }
  300. } else if (blockComment) {
  301. if (isLineTerminator(ch)) {
  302. if (ch === 13 && source.charCodeAt(index + 1) === 10) {
  303. ++index;
  304. }
  305. ++lineNumber;
  306. ++index;
  307. lineStart = index;
  308. if (index >= length) {
  309. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  310. }
  311. } else {
  312. ch = source.charCodeAt(index++);
  313. if (index >= length) {
  314. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  315. }
  316. // Block comment ends with '*/' (char #42, char #47).
  317. if (ch === 42) {
  318. ch = source.charCodeAt(index);
  319. if (ch === 47) {
  320. ++index;
  321. blockComment = false;
  322. }
  323. }
  324. }
  325. } else if (ch === 47) {
  326. ch = source.charCodeAt(index + 1);
  327. // Line comment starts with '//' (char #47, char #47).
  328. if (ch === 47) {
  329. index += 2;
  330. lineComment = true;
  331. } else if (ch === 42) {
  332. // Block comment starts with '/*' (char #47, char #42).
  333. index += 2;
  334. blockComment = true;
  335. if (index >= length) {
  336. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  337. }
  338. } else {
  339. break;
  340. }
  341. } else if (isWhiteSpace(ch)) {
  342. ++index;
  343. } else if (isLineTerminator(ch)) {
  344. ++index;
  345. if (ch === 13 && source.charCodeAt(index) === 10) {
  346. ++index;
  347. }
  348. ++lineNumber;
  349. lineStart = index;
  350. } else {
  351. break;
  352. }
  353. }
  354. }
  355. function scanHexEscape(prefix) {
  356. var i, len, ch, code = 0;
  357. len = (prefix === 'u') ? 4 : 2;
  358. for (i = 0; i < len; ++i) {
  359. if (index < length && isHexDigit(source[index])) {
  360. ch = source[index++];
  361. code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
  362. } else {
  363. return '';
  364. }
  365. }
  366. return String.fromCharCode(code);
  367. }
  368. function getEscapedIdentifier() {
  369. var ch, id;
  370. ch = source.charCodeAt(index++);
  371. id = String.fromCharCode(ch);
  372. // '\u' (char #92, char #117) denotes an escaped character.
  373. if (ch === 92) {
  374. if (source.charCodeAt(index) !== 117) {
  375. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  376. }
  377. ++index;
  378. ch = scanHexEscape('u');
  379. if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
  380. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  381. }
  382. id = ch;
  383. }
  384. while (index < length) {
  385. ch = source.charCodeAt(index);
  386. if (!isIdentifierPart(ch)) {
  387. break;
  388. }
  389. ++index;
  390. id += String.fromCharCode(ch);
  391. // '\u' (char #92, char #117) denotes an escaped character.
  392. if (ch === 92) {
  393. id = id.substr(0, id.length - 1);
  394. if (source.charCodeAt(index) !== 117) {
  395. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  396. }
  397. ++index;
  398. ch = scanHexEscape('u');
  399. if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
  400. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  401. }
  402. id += ch;
  403. }
  404. }
  405. return id;
  406. }
  407. function getIdentifier() {
  408. var start, ch;
  409. start = index++;
  410. while (index < length) {
  411. ch = source.charCodeAt(index);
  412. if (ch === 92) {
  413. // Blackslash (char #92) marks Unicode escape sequence.
  414. index = start;
  415. return getEscapedIdentifier();
  416. }
  417. if (isIdentifierPart(ch)) {
  418. ++index;
  419. } else {
  420. break;
  421. }
  422. }
  423. return source.slice(start, index);
  424. }
  425. function scanIdentifier() {
  426. var start, id, type;
  427. start = index;
  428. // Backslash (char #92) starts an escaped character.
  429. id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier();
  430. // There is no keyword or literal with only one character.
  431. // Thus, it must be an identifier.
  432. if (id.length === 1) {
  433. type = Token.Identifier;
  434. } else if (isKeyword(id)) {
  435. type = Token.Keyword;
  436. } else if (id === 'null') {
  437. type = Token.NullLiteral;
  438. } else if (id === 'true' || id === 'false') {
  439. type = Token.BooleanLiteral;
  440. } else {
  441. type = Token.Identifier;
  442. }
  443. return {
  444. type: type,
  445. value: id,
  446. lineNumber: lineNumber,
  447. lineStart: lineStart,
  448. range: [start, index]
  449. };
  450. }
  451. // 7.7 Punctuators
  452. function scanPunctuator() {
  453. var start = index,
  454. code = source.charCodeAt(index),
  455. code2,
  456. ch1 = source[index],
  457. ch2,
  458. ch3,
  459. ch4;
  460. switch (code) {
  461. // Check for most common single-character punctuators.
  462. case 46: // . dot
  463. case 40: // ( open bracket
  464. case 41: // ) close bracket
  465. case 59: // ; semicolon
  466. case 44: // , comma
  467. case 123: // { open curly brace
  468. case 125: // } close curly brace
  469. case 91: // [
  470. case 93: // ]
  471. case 58: // :
  472. case 63: // ?
  473. case 126: // ~
  474. ++index;
  475. if (extra.tokenize) {
  476. if (code === 40) {
  477. extra.openParenToken = extra.tokens.length;
  478. } else if (code === 123) {
  479. extra.openCurlyToken = extra.tokens.length;
  480. }
  481. }
  482. return {
  483. type: Token.Punctuator,
  484. value: String.fromCharCode(code),
  485. lineNumber: lineNumber,
  486. lineStart: lineStart,
  487. range: [start, index]
  488. };
  489. default:
  490. code2 = source.charCodeAt(index + 1);
  491. // '=' (char #61) marks an assignment or comparison operator.
  492. if (code2 === 61) {
  493. switch (code) {
  494. case 37: // %
  495. case 38: // &
  496. case 42: // *:
  497. case 43: // +
  498. case 45: // -
  499. case 47: // /
  500. case 60: // <
  501. case 62: // >
  502. case 94: // ^
  503. case 124: // |
  504. index += 2;
  505. return {
  506. type: Token.Punctuator,
  507. value: String.fromCharCode(code) + String.fromCharCode(code2),
  508. lineNumber: lineNumber,
  509. lineStart: lineStart,
  510. range: [start, index]
  511. };
  512. case 33: // !
  513. case 61: // =
  514. index += 2;
  515. // !== and ===
  516. if (source.charCodeAt(index) === 61) {
  517. ++index;
  518. }
  519. return {
  520. type: Token.Punctuator,
  521. value: source.slice(start, index),
  522. lineNumber: lineNumber,
  523. lineStart: lineStart,
  524. range: [start, index]
  525. };
  526. default:
  527. break;
  528. }
  529. }
  530. break;
  531. }
  532. // Peek more characters.
  533. ch2 = source[index + 1];
  534. ch3 = source[index + 2];
  535. ch4 = source[index + 3];
  536. // 4-character punctuator: >>>=
  537. if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
  538. if (ch4 === '=') {
  539. index += 4;
  540. return {
  541. type: Token.Punctuator,
  542. value: '>>>=',
  543. lineNumber: lineNumber,
  544. lineStart: lineStart,
  545. range: [start, index]
  546. };
  547. }
  548. }
  549. // 3-character punctuators: === !== >>> <<= >>=
  550. if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
  551. index += 3;
  552. return {
  553. type: Token.Punctuator,
  554. value: '>>>',
  555. lineNumber: lineNumber,
  556. lineStart: lineStart,
  557. range: [start, index]
  558. };
  559. }
  560. if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
  561. index += 3;
  562. return {
  563. type: Token.Punctuator,
  564. value: '<<=',
  565. lineNumber: lineNumber,
  566. lineStart: lineStart,
  567. range: [start, index]
  568. };
  569. }
  570. if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
  571. index += 3;
  572. return {
  573. type: Token.Punctuator,
  574. value: '>>=',
  575. lineNumber: lineNumber,
  576. lineStart: lineStart,
  577. range: [start, index]
  578. };
  579. }
  580. // Other 2-character punctuators: ++ -- << >> && ||
  581. if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
  582. index += 2;
  583. return {
  584. type: Token.Punctuator,
  585. value: ch1 + ch2,
  586. lineNumber: lineNumber,
  587. lineStart: lineStart,
  588. range: [start, index]
  589. };
  590. }
  591. if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
  592. ++index;
  593. return {
  594. type: Token.Punctuator,
  595. value: ch1,
  596. lineNumber: lineNumber,
  597. lineStart: lineStart,
  598. range: [start, index]
  599. };
  600. }
  601. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  602. }
  603. // 7.8.3 Numeric Literals
  604. function scanHexLiteral(start) {
  605. var number = '';
  606. while (index < length) {
  607. if (!isHexDigit(source[index])) {
  608. break;
  609. }
  610. number += source[index++];
  611. }
  612. if (number.length === 0) {
  613. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  614. }
  615. if (isIdentifierStart(source.charCodeAt(index))) {
  616. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  617. }
  618. return {
  619. type: Token.NumericLiteral,
  620. value: parseInt('0x' + number, 16),
  621. lineNumber: lineNumber,
  622. lineStart: lineStart,
  623. range: [start, index]
  624. };
  625. }
  626. function scanOctalLiteral(start) {
  627. var number = '0' + source[index++];
  628. while (index < length) {
  629. if (!isOctalDigit(source[index])) {
  630. break;
  631. }
  632. number += source[index++];
  633. }
  634. if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
  635. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  636. }
  637. return {
  638. type: Token.NumericLiteral,
  639. value: parseInt(number, 8),
  640. octal: true,
  641. lineNumber: lineNumber,
  642. lineStart: lineStart,
  643. range: [start, index]
  644. };
  645. }
  646. function scanNumericLiteral() {
  647. var number, start, ch;
  648. ch = source[index];
  649. assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
  650. 'Numeric literal must start with a decimal digit or a decimal point');
  651. start = index;
  652. number = '';
  653. if (ch !== '.') {
  654. number = source[index++];
  655. ch = source[index];
  656. // Hex number starts with '0x'.
  657. // Octal number starts with '0'.
  658. if (number === '0') {
  659. if (ch === 'x' || ch === 'X') {
  660. ++index;
  661. return scanHexLiteral(start);
  662. }
  663. if (isOctalDigit(ch)) {
  664. return scanOctalLiteral(start);
  665. }
  666. // decimal number starts with '0' such as '09' is illegal.
  667. if (ch && isDecimalDigit(ch.charCodeAt(0))) {
  668. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  669. }
  670. }
  671. while (isDecimalDigit(source.charCodeAt(index))) {
  672. number += source[index++];
  673. }
  674. ch = source[index];
  675. }
  676. if (ch === '.') {
  677. number += source[index++];
  678. while (isDecimalDigit(source.charCodeAt(index))) {
  679. number += source[index++];
  680. }
  681. ch = source[index];
  682. }
  683. if (ch === 'e' || ch === 'E') {
  684. number += source[index++];
  685. ch = source[index];
  686. if (ch === '+' || ch === '-') {
  687. number += source[index++];
  688. }
  689. if (isDecimalDigit(source.charCodeAt(index))) {
  690. while (isDecimalDigit(source.charCodeAt(index))) {
  691. number += source[index++];
  692. }
  693. } else {
  694. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  695. }
  696. }
  697. if (isIdentifierStart(source.charCodeAt(index))) {
  698. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  699. }
  700. return {
  701. type: Token.NumericLiteral,
  702. value: parseFloat(number),
  703. lineNumber: lineNumber,
  704. lineStart: lineStart,
  705. range: [start, index]
  706. };
  707. }
  708. // 7.8.4 String Literals
  709. function scanStringLiteral() {
  710. var str = '', quote, start, ch, code, unescaped, restore, octal = false;
  711. quote = source[index];
  712. assert((quote === '\'' || quote === '"'),
  713. 'String literal must starts with a quote');
  714. start = index;
  715. ++index;
  716. while (index < length) {
  717. ch = source[index++];
  718. if (ch === quote) {
  719. quote = '';
  720. break;
  721. } else if (ch === '\\') {
  722. ch = source[index++];
  723. if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
  724. switch (ch) {
  725. case 'n':
  726. str += '\n';
  727. break;
  728. case 'r':
  729. str += '\r';
  730. break;
  731. case 't':
  732. str += '\t';
  733. break;
  734. case 'u':
  735. case 'x':
  736. restore = index;
  737. unescaped = scanHexEscape(ch);
  738. if (unescaped) {
  739. str += unescaped;
  740. } else {
  741. index = restore;
  742. str += ch;
  743. }
  744. break;
  745. case 'b':
  746. str += '\b';
  747. break;
  748. case 'f':
  749. str += '\f';
  750. break;
  751. case 'v':
  752. str += '\v';
  753. break;
  754. default:
  755. if (isOctalDigit(ch)) {
  756. code = '01234567'.indexOf(ch);
  757. // \0 is not octal escape sequence
  758. if (code !== 0) {
  759. octal = true;
  760. }
  761. if (index < length && isOctalDigit(source[index])) {
  762. octal = true;
  763. code = code * 8 + '01234567'.indexOf(source[index++]);
  764. // 3 digits are only allowed when string starts
  765. // with 0, 1, 2, 3
  766. if ('0123'.indexOf(ch) >= 0 &&
  767. index < length &&
  768. isOctalDigit(source[index])) {
  769. code = code * 8 + '01234567'.indexOf(source[index++]);
  770. }
  771. }
  772. str += String.fromCharCode(code);
  773. } else {
  774. str += ch;
  775. }
  776. break;
  777. }
  778. } else {
  779. ++lineNumber;
  780. if (ch === '\r' && source[index] === '\n') {
  781. ++index;
  782. }
  783. }
  784. } else if (isLineTerminator(ch.charCodeAt(0))) {
  785. break;
  786. } else {
  787. str += ch;
  788. }
  789. }
  790. if (quote !== '') {
  791. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  792. }
  793. return {
  794. type: Token.StringLiteral,
  795. value: str,
  796. octal: octal,
  797. lineNumber: lineNumber,
  798. lineStart: lineStart,
  799. range: [start, index]
  800. };
  801. }
  802. function scanRegExp() {
  803. var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;
  804. lookahead = null;
  805. skipComment();
  806. start = index;
  807. ch = source[index];
  808. assert(ch === '/', 'Regular expression literal must start with a slash');
  809. str = source[index++];
  810. while (index < length) {
  811. ch = source[index++];
  812. str += ch;
  813. if (classMarker) {
  814. // NOTE: fix bug: /[\]/]/
  815. if (ch === ']' && ( source[ index - 2 ] !== '\\' || source[ index - 3 ] === '\\') ) {
  816. classMarker = false;
  817. }
  818. } else {
  819. if (ch === '\\') {
  820. ch = source[index++];
  821. // ECMA-262 7.8.5
  822. if (isLineTerminator(ch.charCodeAt(0))) {
  823. throwError({}, Messages.UnterminatedRegExp);
  824. }
  825. str += ch;
  826. } else if (ch === '/') {
  827. terminated = true;
  828. break;
  829. } else if (ch === '[') {
  830. classMarker = true;
  831. } else if (isLineTerminator(ch.charCodeAt(0))) {
  832. throwError({}, Messages.UnterminatedRegExp);
  833. }
  834. }
  835. }
  836. if (!terminated) {
  837. throwError({}, Messages.UnterminatedRegExp);
  838. }
  839. // Exclude leading and trailing slash.
  840. pattern = str.substr(1, str.length - 2);
  841. flags = '';
  842. while (index < length) {
  843. ch = source[index];
  844. if (!isIdentifierPart(ch.charCodeAt(0))) {
  845. break;
  846. }
  847. ++index;
  848. if (ch === '\\' && index < length) {
  849. ch = source[index];
  850. if (ch === 'u') {
  851. ++index;
  852. restore = index;
  853. ch = scanHexEscape('u');
  854. if (ch) {
  855. flags += ch;
  856. for (str += '\\u'; restore < index; ++restore) {
  857. str += source[restore];
  858. }
  859. } else {
  860. index = restore;
  861. flags += 'u';
  862. str += '\\u';
  863. }
  864. } else {
  865. str += '\\';
  866. }
  867. } else {
  868. flags += ch;
  869. str += ch;
  870. }
  871. }
  872. try {
  873. value = new RegExp(pattern, flags);
  874. } catch (e) {
  875. throwError({}, Messages.InvalidRegExp);
  876. }
  877. peek();
  878. if (extra.tokenize) {
  879. return {
  880. type: Token.RegularExpression,
  881. value: value,
  882. lineNumber: lineNumber,
  883. lineStart: lineStart,
  884. range: [start, index]
  885. };
  886. }
  887. return {
  888. literal: str,
  889. value: value,
  890. range: [start, index]
  891. };
  892. }
  893. function isIdentifierName(token) {
  894. return token.type === Token.Identifier ||
  895. token.type === Token.Keyword ||
  896. token.type === Token.BooleanLiteral ||
  897. token.type === Token.NullLiteral;
  898. }
  899. function advanceSlash() {
  900. var prevToken,
  901. checkToken;
  902. // Using the following algorithm:
  903. // https://github.com/mozilla/sweet.js/wiki/design
  904. prevToken = extra.tokens[extra.tokens.length - 1];
  905. if (!prevToken) {
  906. // Nothing before that: it cannot be a division.
  907. return scanRegExp();
  908. }
  909. if (prevToken.type === "Punctuator") {
  910. if (prevToken.value === ")") {
  911. checkToken = extra.tokens[extra.openParenToken - 1];
  912. if (checkToken &&
  913. checkToken.type === "Keyword" &&
  914. (checkToken.value === "if" ||
  915. checkToken.value === "while" ||
  916. checkToken.value === "for" ||
  917. checkToken.value === "with")) {
  918. return scanRegExp();
  919. }
  920. return scanPunctuator();
  921. }
  922. if (prevToken.value === "}") {
  923. // Dividing a function by anything makes little sense,
  924. // but we have to check for that.
  925. if (extra.tokens[extra.openCurlyToken - 3] &&
  926. extra.tokens[extra.openCurlyToken - 3].type === "Keyword") {
  927. // Anonymous function.
  928. checkToken = extra.tokens[extra.openCurlyToken - 4];
  929. if (!checkToken) {
  930. return scanPunctuator();
  931. }
  932. } else if (extra.tokens[extra.openCurlyToken - 4] &&
  933. extra.tokens[extra.openCurlyToken - 4].type === "Keyword") {
  934. // Named function.
  935. checkToken = extra.tokens[extra.openCurlyToken - 5];
  936. if (!checkToken) {
  937. return scanRegExp();
  938. }
  939. } else {
  940. return scanPunctuator();
  941. }
  942. // checkToken determines whether the function is
  943. // a declaration or an expression.
  944. if (FnExprTokens.indexOf(checkToken.value) >= 0) {
  945. // It is an expression.
  946. return scanPunctuator();
  947. }
  948. // It is a declaration.
  949. return scanRegExp();
  950. }
  951. return scanRegExp();
  952. }
  953. if (prevToken.type === "Keyword") {
  954. return scanRegExp();
  955. }
  956. return scanPunctuator();
  957. }
  958. function advance() {
  959. var ch;
  960. skipComment();
  961. if (index >= length) {
  962. return {
  963. type: Token.EOF,
  964. lineNumber: lineNumber,
  965. lineStart: lineStart,
  966. range: [index, index]
  967. };
  968. }
  969. ch = source.charCodeAt(index);
  970. // Very common: ( and ) and ;
  971. if (ch === 40 || ch === 41 || ch === 58) {
  972. return scanPunctuator();
  973. }
  974. // String literal starts with single quote (#39) or double quote (#34).
  975. if (ch === 39 || ch === 34) {
  976. return scanStringLiteral();
  977. }
  978. if (isIdentifierStart(ch)) {
  979. return scanIdentifier();
  980. }
  981. // Dot (.) char #46 can also start a floating-point number, hence the need
  982. // to check the next character.
  983. if (ch === 46) {
  984. if (isDecimalDigit(source.charCodeAt(index + 1))) {
  985. return scanNumericLiteral();
  986. }
  987. return scanPunctuator();
  988. }
  989. if (isDecimalDigit(ch)) {
  990. return scanNumericLiteral();
  991. }
  992. // Slash (/) char #47 can also start a regex.
  993. if (extra.tokenize && ch === 47) {
  994. return advanceSlash();
  995. }
  996. return scanPunctuator();
  997. }
  998. function lex() {
  999. var token;
  1000. token = lookahead;
  1001. index = token.range[1];
  1002. lineNumber = token.lineNumber;
  1003. lineStart = token.lineStart;
  1004. lookahead = advance();
  1005. index = token.range[1];
  1006. lineNumber = token.lineNumber;
  1007. lineStart = token.lineStart;
  1008. return token;
  1009. }
  1010. function peek() {
  1011. var pos, line, start;
  1012. pos = index;
  1013. line = lineNumber;
  1014. start = lineStart;
  1015. lookahead = advance();
  1016. index = pos;
  1017. lineNumber = line;
  1018. lineStart = start;
  1019. }
  1020. SyntaxTreeDelegate = {
  1021. name: 'SyntaxTree',
  1022. postProcess: function (node) {
  1023. return node;
  1024. },
  1025. createArrayExpression: function (elements) {
  1026. return {
  1027. type: Syntax.ArrayExpression,
  1028. elements: elements
  1029. };
  1030. },
  1031. createAssignmentExpression: function (operator, left, right) {
  1032. return {
  1033. type: Syntax.AssignmentExpression,
  1034. operator: operator,
  1035. left: left,
  1036. right: right
  1037. };
  1038. },
  1039. createBinaryExpression: function (operator, left, right) {
  1040. var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
  1041. Syntax.BinaryExpression;
  1042. return {
  1043. type: type,
  1044. operator: operator,
  1045. left: left,
  1046. right: right
  1047. };
  1048. },
  1049. createBlockStatement: function (body) {
  1050. return {
  1051. type: Syntax.BlockStatement,
  1052. body: body
  1053. };
  1054. },
  1055. createBreakStatement: function (label) {
  1056. return {
  1057. type: Syntax.BreakStatement,
  1058. label: label
  1059. };
  1060. },
  1061. createCallExpression: function (callee, args) {
  1062. return {
  1063. type: Syntax.CallExpression,
  1064. callee: callee,
  1065. 'arguments': args
  1066. };
  1067. },
  1068. createCatchClause: function (param, body) {
  1069. return {
  1070. type: Syntax.CatchClause,
  1071. param: param,
  1072. body: body
  1073. };
  1074. },
  1075. createConditionalExpression: function (test, consequent, alternate) {
  1076. return {
  1077. type: Syntax.ConditionalExpression,
  1078. test: test,
  1079. consequent: consequent,
  1080. alternate: alternate
  1081. };
  1082. },
  1083. createContinueStatement: function (label) {
  1084. return {
  1085. type: Syntax.ContinueStatement,
  1086. label: label
  1087. };
  1088. },
  1089. createDebuggerStatement: function () {
  1090. return {
  1091. type: Syntax.DebuggerStatement
  1092. };
  1093. },
  1094. createDoWhileStatement: function (body, test) {
  1095. return {
  1096. type: Syntax.DoWhileStatement,
  1097. body: body,
  1098. test: test
  1099. };
  1100. },
  1101. createEmptyStatement: function () {
  1102. return {
  1103. type: Syntax.EmptyStatement
  1104. };
  1105. },
  1106. createExpressionStatement: function (expression) {
  1107. return {
  1108. type: Syntax.ExpressionStatement,
  1109. expression: expression
  1110. };
  1111. },
  1112. createForStatement: function (init, test, update, body) {
  1113. return {
  1114. type: Syntax.ForStatement,
  1115. init: init,
  1116. test: test,
  1117. update: update,
  1118. body: body
  1119. };
  1120. },
  1121. createForInStatement: function (left, right, body) {
  1122. return {
  1123. type: Syntax.ForInStatement,
  1124. left: left,
  1125. right: right,
  1126. body: body,
  1127. each: false
  1128. };
  1129. },
  1130. createFunctionDeclaration: function (id, params, defaults, body) {
  1131. return {
  1132. type: Syntax.FunctionDeclaration,
  1133. id: id,
  1134. params: params,
  1135. defaults: defaults,
  1136. body: body,
  1137. rest: null,
  1138. generator: false,
  1139. expression: false
  1140. };
  1141. },
  1142. createFunctionExpression: function (id, params, defaults, body) {
  1143. return {
  1144. type: Syntax.FunctionExpression,
  1145. id: id,
  1146. params: params,
  1147. defaults: defaults,
  1148. body: body,
  1149. rest: null,
  1150. generator: false,
  1151. expression: false
  1152. };
  1153. },
  1154. createIdentifier: function (name) {
  1155. return {
  1156. type: Syntax.Identifier,
  1157. name: name
  1158. };
  1159. },
  1160. createIfStatement: function (test, consequent, alternate) {
  1161. return {
  1162. type: Syntax.IfStatement,
  1163. test: test,
  1164. consequent: consequent,
  1165. alternate: alternate
  1166. };
  1167. },
  1168. createLabeledStatement: function (label, body) {
  1169. return {
  1170. type: Syntax.LabeledStatement,
  1171. label: label,
  1172. body: body
  1173. };
  1174. },
  1175. createLiteral: function (token) {
  1176. return {
  1177. type: Syntax.Literal,
  1178. value: token.value,
  1179. raw: source.slice(token.range[0], token.range[1])
  1180. };
  1181. },
  1182. createMemberExpression: function (accessor, object, property) {
  1183. return {
  1184. type: Syntax.MemberExpression,
  1185. computed: accessor === '[',
  1186. object: object,
  1187. property: property
  1188. };
  1189. },
  1190. createNewExpression: function (callee, args) {
  1191. return {
  1192. type: Syntax.NewExpression,
  1193. callee: callee,
  1194. 'arguments': args
  1195. };
  1196. },
  1197. createObjectExpression: function (properties) {
  1198. return {
  1199. type: Syntax.ObjectExpression,
  1200. properties: properties
  1201. };
  1202. },
  1203. createPostfixExpression: function (operator, argument) {
  1204. return {
  1205. type: Syntax.UpdateExpression,
  1206. operator: operator,
  1207. argument: argument,
  1208. prefix: false
  1209. };
  1210. },
  1211. createProgram: function (body) {
  1212. return {
  1213. type: Syntax.Program,
  1214. body: body
  1215. };
  1216. },
  1217. createProperty: function (kind, key, value) {
  1218. return {
  1219. type: Syntax.Property,
  1220. key: key,
  1221. value: value,
  1222. kind: kind
  1223. };
  1224. },
  1225. createReturnStatement: function (argument) {
  1226. return {
  1227. type: Syntax.ReturnStatement,
  1228. argument: argument
  1229. };
  1230. },
  1231. createSequenceExpression: function (expressions) {
  1232. return {
  1233. type: Syntax.SequenceExpression,
  1234. expressions: expressions
  1235. };
  1236. },
  1237. createSwitchCase: function (test, consequent) {
  1238. return {
  1239. type: Syntax.SwitchCase,
  1240. test: test,
  1241. consequent: consequent
  1242. };
  1243. },
  1244. createSwitchStatement: function (discriminant, cases) {
  1245. return {
  1246. type: Syntax.SwitchStatement,
  1247. discriminant: discriminant,
  1248. cases: cases
  1249. };
  1250. },
  1251. createThisExpression: function () {
  1252. return {
  1253. type: Syntax.ThisExpression
  1254. };
  1255. },
  1256. createThrowStatement: function (argument) {
  1257. return {
  1258. type: Syntax.ThrowStatement,
  1259. argument: argument
  1260. };
  1261. },
  1262. createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
  1263. return {
  1264. type: Syntax.TryStatement,
  1265. block: block,
  1266. guardedHandlers: guardedHandlers,
  1267. handlers: handlers,
  1268. finalizer: finalizer
  1269. };
  1270. },
  1271. createUnaryExpression: function (operator, argument) {
  1272. if (operator === '++' || operator === '--') {
  1273. return {
  1274. type: Syntax.UpdateExpression,
  1275. operator: operator,
  1276. argument: argument,
  1277. prefix: true
  1278. };
  1279. }
  1280. return {
  1281. type: Syntax.UnaryExpression,
  1282. operator: operator,
  1283. argument: argument
  1284. };
  1285. },
  1286. createVariableDeclaration: function (declarations, kind) {
  1287. return {
  1288. type: Syntax.VariableDeclaration,
  1289. declarations: declarations,
  1290. kind: kind
  1291. };
  1292. },
  1293. createVariableDeclarator: function (id, init) {
  1294. return {
  1295. type: Syntax.VariableDeclarator,
  1296. id: id,
  1297. init: init
  1298. };
  1299. },
  1300. createWhileStatement: function (test, body) {
  1301. return {
  1302. type: Syntax.WhileStatement,
  1303. test: test,
  1304. body: body
  1305. };
  1306. },
  1307. createWithStatement: function (object, body) {
  1308. return {
  1309. type: Syntax.WithStatement,
  1310. object: object,
  1311. body: body
  1312. };
  1313. }
  1314. };
  1315. // Return true if there is a line terminator before the next token.
  1316. function peekLineTerminator() {
  1317. var pos, line, start, found;
  1318. pos = index;
  1319. line = lineNumber;
  1320. start = lineStart;
  1321. skipComment();
  1322. found = lineNumber !== line;
  1323. index = pos;
  1324. lineNumber = line;
  1325. lineStart = start;
  1326. return found;
  1327. }
  1328. // Throw an exception
  1329. function throwError(token, messageFormat) {
  1330. var error,
  1331. args = Array.prototype.slice.call(arguments, 2),
  1332. msg = messageFormat.replace(
  1333. /%(\d)/g,
  1334. function (whole, index) {
  1335. assert(index < args.length, 'Message reference must be in range');
  1336. return args[index];
  1337. }
  1338. );
  1339. if (typeof token.lineNumber === 'number') {
  1340. error = new Error('Line ' + token.lineNumber + ': ' + msg);
  1341. error.index = token.range[0];
  1342. error.lineNumber = token.lineNumber;
  1343. error.column = token.range[0] - lineStart + 1;
  1344. } else {
  1345. error = new Error('Line ' + lineNumber + ': ' + msg);
  1346. error.index = index;
  1347. error.lineNumber = lineNumber;
  1348. error.column = index - lineStart + 1;
  1349. }
  1350. error.description = msg;
  1351. throw error;
  1352. }
  1353. function throwErrorTolerant() {
  1354. try {
  1355. throwError.apply(null, arguments);
  1356. } catch (e) {
  1357. if (extra.errors) {
  1358. extra.errors.push(e);
  1359. } else {
  1360. throw e;
  1361. }
  1362. }
  1363. }
  1364. // Throw an exception because of the token.
  1365. function throwUnexpected(token) {
  1366. if (token.type === Token.EOF) {
  1367. throwError(token, Messages.UnexpectedEOS);
  1368. }
  1369. if (token.type === Token.NumericLiteral) {
  1370. throwError(token, Messages.UnexpectedNumber);
  1371. }
  1372. if (token.type === Token.StringLiteral) {
  1373. throwError(token, Messages.UnexpectedString);
  1374. }
  1375. if (token.type === Token.Identifier) {
  1376. throwError(token, Messages.UnexpectedIdentifier);
  1377. }
  1378. if (token.type === Token.Keyword) {
  1379. if (isFutureReservedWord(token.value)) {
  1380. throwError(token, Messages.UnexpectedReserved);
  1381. } else if (strict && isStrictModeReservedWord(token.value)) {
  1382. throwErrorTolerant(token, Messages.StrictReservedWord);
  1383. return;
  1384. }
  1385. throwError(token, Messages.UnexpectedToken, token.value);
  1386. }
  1387. // BooleanLiteral, NullLiteral, or Punctuator.
  1388. throwError(token, Messages.UnexpectedToken, token.value);
  1389. }
  1390. // Expect the next token to match the specified punctuator.
  1391. // If not, an exception will be thrown.
  1392. function expect(value) {
  1393. var token = lex();
  1394. if (token.type !== Token.Punctuator || token.value !== value) {
  1395. throwUnexpected(token);
  1396. }
  1397. }
  1398. // Expect the next token to match the specified keyword.
  1399. // If not, an exception will be thrown.
  1400. function expectKeyword(keyword) {
  1401. var token = lex();
  1402. if (token.type !== Token.Keyword || token.value !== keyword) {
  1403. throwUnexpected(token);
  1404. }
  1405. }
  1406. // Return true if the next token matches the specified punctuator.
  1407. function match(value) {
  1408. return lookahead.type === Token.Punctuator && lookahead.value === value;
  1409. }
  1410. // Return true if the next token matches the specified keyword
  1411. function matchKeyword(keyword) {
  1412. return lookahead.type === Token.Keyword && lookahead.value === keyword;
  1413. }
  1414. // Return true if the next token is an assignment operator
  1415. function matchAssign() {
  1416. var op;
  1417. if (lookahead.type !== Token.Punctuator) {
  1418. return false;
  1419. }
  1420. op = lookahead.value;
  1421. return op === '=' ||
  1422. op === '*=' ||
  1423. op === '/=' ||
  1424. op === '%=' ||
  1425. op === '+=' ||
  1426. op === '-=' ||
  1427. op === '<<=' ||
  1428. op === '>>=' ||
  1429. op === '>>>=' ||
  1430. op === '&=' ||
  1431. op === '^=' ||
  1432. op === '|=';
  1433. }
  1434. function consumeSemicolon() {
  1435. var line;
  1436. // Catch the very common case first: immediately a semicolon (char #59).
  1437. if (source.charCodeAt(index) === 59) {
  1438. lex();
  1439. return;
  1440. }
  1441. line = lineNumber;
  1442. skipComment();
  1443. if (lineNumber !== line) {
  1444. return;
  1445. }
  1446. if (match(';')) {
  1447. lex();
  1448. return;
  1449. }
  1450. if (lookahead.type !== Token.EOF && !match('}')) {
  1451. throwUnexpected(lookahead);
  1452. }
  1453. }
  1454. // Return true if provided expression is LeftHandSideExpression
  1455. function isLeftHandSide(expr) {
  1456. return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
  1457. }
  1458. // 11.1.4 Array Initialiser
  1459. function parseArrayInitialiser() {
  1460. var elements = [];
  1461. expect('[');
  1462. while (!match(']')) {
  1463. if (match(',')) {
  1464. lex();
  1465. elements.push(null);
  1466. } else {
  1467. elements.push(parseAssignmentExpression());
  1468. if (!match(']')) {
  1469. expect(',');
  1470. }
  1471. }
  1472. }
  1473. expect(']');
  1474. return delegate.createArrayExpression(elements);
  1475. }
  1476. // 11.1.5 Object Initialiser
  1477. function parsePropertyFunction(param, first) {
  1478. var previousStrict, body;
  1479. previousStrict = strict;
  1480. body = parseFunctionSourceElements();
  1481. if (first && strict && isRestrictedWord(param[0].name)) {
  1482. throwErrorTolerant(first, Messages.StrictParamName);
  1483. }
  1484. strict = previousStrict;
  1485. return delegate.createFunctionExpression(null, param, [], body);
  1486. }
  1487. function parseObjectPropertyKey() {
  1488. var token = lex();
  1489. // Note: This function is called only from parseObjectProperty(), where
  1490. // EOF and Punctuator tokens are already filtered out.
  1491. if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
  1492. if (strict && token.octal) {
  1493. throwErrorTolerant(token, Messages.StrictOctalLiteral);
  1494. }
  1495. return delegate.createLiteral(token);
  1496. }
  1497. return delegate.createIdentifier(token.value);
  1498. }
  1499. function parseObjectProperty() {
  1500. var token, key, id, value, param;
  1501. token = lookahead;
  1502. if (token.type === Token.Identifier) {
  1503. id = parseObjectPropertyKey();
  1504. // Property Assignment: Getter and Setter.
  1505. if (token.value === 'get' && !match(':')) {
  1506. key = parseObjectPropertyKey();
  1507. expect('(');
  1508. expect(')');
  1509. value = parsePropertyFunction([]);
  1510. return delegate.createProperty('get', key, value);
  1511. }
  1512. if (token.value === 'set' && !match(':')) {
  1513. key = parseObjectPropertyKey();
  1514. expect('(');
  1515. token = lookahead;
  1516. if (token.type !== Token.Identifier) {
  1517. throwUnexpected(lex());
  1518. }
  1519. param = [ parseVariableIdentifier() ];
  1520. expect(')');
  1521. value = parsePropertyFunction(param, token);
  1522. return delegate.createProperty('set', key, value);
  1523. }
  1524. expect(':');
  1525. value = parseAssignmentExpression();
  1526. return delegate.createProperty('init', id, value);
  1527. }
  1528. if (token.type === Token.EOF || token.type === Token.Punctuator) {
  1529. throwUnexpected(token);
  1530. } else {
  1531. key = parseObjectPropertyKey();
  1532. expect(':');
  1533. value = parseAssignmentExpression();
  1534. return delegate.createProperty('init', key, value);
  1535. }
  1536. }
  1537. function parseObjectInitialiser() {
  1538. var properties = [], property, name, key, kind, map = {}, toString = String;
  1539. expect('{');
  1540. while (!match('}')) {
  1541. property = parseObjectProperty();
  1542. if (property.key.type === Syntax.Identifier) {
  1543. name = property.key.name;
  1544. } else {
  1545. name = toString(property.key.value);
  1546. }
  1547. kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
  1548. key = '$' + name;
  1549. if (Object.prototype.hasOwnProperty.call(map, key)) {
  1550. if (map[key] === PropertyKind.Data) {
  1551. if (strict && kind === PropertyKind.Data) {
  1552. throwErrorTolerant({}, Messages.StrictDuplicateProperty);
  1553. } else if (kind !== PropertyKind.Data) {
  1554. throwErrorTolerant({}, Messages.AccessorDataProperty);
  1555. }
  1556. } else {
  1557. if (kind === PropertyKind.Data) {
  1558. throwErrorTolerant({}, Messages.AccessorDataProperty);
  1559. } else if (map[key] & kind) {
  1560. throwErrorTolerant({}, Messages.AccessorGetSet);
  1561. }
  1562. }
  1563. map[key] |= kind;
  1564. } else {
  1565. map[key] = kind;
  1566. }
  1567. properties.push(property);
  1568. if (!match('}')) {
  1569. expect(',');
  1570. }
  1571. }
  1572. expect('}');
  1573. return delegate.createObjectExpression(properties);
  1574. }
  1575. // 11.1.6 The Grouping Operator
  1576. function parseGroupExpression() {
  1577. var expr;
  1578. expect('(');
  1579. expr = parseExpression();
  1580. expect(')');
  1581. return expr;
  1582. }
  1583. // 11.1 Primary Expressions
  1584. function parsePrimaryExpression() {
  1585. var type, token;
  1586. type = lookahead.type;
  1587. if (type === Token.Identifier) {
  1588. return delegate.createIdentifier(lex().value);
  1589. }
  1590. if (type === Token.StringLiteral || type === Token.NumericLiteral) {
  1591. if (strict && lookahead.octal) {
  1592. throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
  1593. }
  1594. return delegate.createLiteral(lex());
  1595. }
  1596. if (type === Token.Keyword) {
  1597. if (matchKeyword('this')) {
  1598. lex();
  1599. return delegate.createThisExpression();
  1600. }
  1601. if (matchKeyword('function')) {
  1602. return parseFunctionExpression();
  1603. }
  1604. }
  1605. if (type === Token.BooleanLiteral) {
  1606. token = lex();
  1607. token.value = (token.value === 'true');
  1608. return delegate.createLiteral(token);
  1609. }
  1610. if (type === Token.NullLiteral) {
  1611. token = lex();
  1612. token.value = null;
  1613. return delegate.createLiteral(token);
  1614. }
  1615. if (match('[')) {
  1616. return parseArrayInitialiser();
  1617. }
  1618. if (match('{')) {
  1619. return parseObjectInitialiser();
  1620. }
  1621. if (match('(')) {
  1622. return parseGroupExpression();
  1623. }
  1624. if (match('/') || match('/=')) {
  1625. return delegate.createLiteral(scanRegExp());
  1626. }
  1627. return throwUnexpected(lex());
  1628. }
  1629. // 11.2 Left-Hand-Side Expressions
  1630. function parseArguments() {
  1631. var args = [];
  1632. expect('(');
  1633. if (!match(')')) {
  1634. while (index < length) {
  1635. args.push(parseAssignmentExpression());
  1636. if (match(')')) {
  1637. break;
  1638. }
  1639. expect(',');
  1640. }
  1641. }
  1642. expect(')');
  1643. return args;
  1644. }
  1645. function parseNonComputedProperty() {
  1646. var token = lex();
  1647. if (!isIdentifierName(token)) {
  1648. throwUnexpected(token);
  1649. }
  1650. return delegate.createIdentifier(token.value);
  1651. }
  1652. function parseNonComputedMember() {
  1653. expect('.');
  1654. return parseNonComputedProperty();
  1655. }
  1656. function parseComputedMember() {
  1657. var expr;
  1658. expect('[');
  1659. expr = parseExpression();
  1660. expect(']');
  1661. return expr;
  1662. }
  1663. function parseNewExpression() {
  1664. var callee, args;
  1665. expectKeyword('new');
  1666. callee = parseLeftHandSideExpression();
  1667. args = match('(') ? parseArguments() : [];
  1668. return delegate.createNewExpression(callee, args);
  1669. }
  1670. function parseLeftHandSideExpressionAllowCall() {
  1671. var expr, args, property;
  1672. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  1673. while (match('.') || match('[') || match('(')) {
  1674. if (match('(')) {
  1675. args = parseArguments();
  1676. expr = delegate.createCallExpression(expr, args);
  1677. } else if (match('[')) {
  1678. property = parseComputedMember();
  1679. expr = delegate.createMemberExpression('[', expr, property);
  1680. } else {
  1681. property = parseNonComputedMember();
  1682. expr = delegate.createMemberExpression('.', expr, property);
  1683. }
  1684. }
  1685. return expr;
  1686. }
  1687. function parseLeftHandSideExpression() {
  1688. var expr, property;
  1689. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  1690. while (match('.') || match('[')) {
  1691. if (match('[')) {
  1692. property = parseComputedMember();
  1693. expr = delegate.createMemberExpression('[', expr, property);
  1694. } else {
  1695. property = parseNonComputedMember();
  1696. expr = delegate.createMemberExpression('.', expr, property);
  1697. }
  1698. }
  1699. return expr;
  1700. }
  1701. // 11.3 Postfix Expressions
  1702. function parsePostfixExpression() {
  1703. var expr = parseLeftHandSideExpressionAllowCall(), token;
  1704. if (lookahead.type !== Token.Punctuator) {
  1705. return expr;
  1706. }
  1707. if ((match('++') || match('--')) && !peekLineTerminator()) {
  1708. // 11.3.1, 11.3.2
  1709. if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
  1710. throwErrorTolerant({}, Messages.StrictLHSPostfix);
  1711. }
  1712. if (!isLeftHandSide(expr)) {
  1713. throwError({}, Messages.InvalidLHSInAssignment);
  1714. }
  1715. token = lex();
  1716. expr = delegate.createPostfixExpression(token.value, expr);
  1717. }
  1718. return expr;
  1719. }
  1720. // 11.4 Unary Operators
  1721. function parseUnaryExpression() {
  1722. var token, expr;
  1723. if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
  1724. return parsePostfixExpression();
  1725. }
  1726. if (match('++') || match('--')) {
  1727. token = lex();
  1728. expr = parseUnaryExpression();
  1729. // 11.4.4, 11.4.5
  1730. if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
  1731. throwErrorTolerant({}, Messages.StrictLHSPrefix);
  1732. }
  1733. if (!isLeftHandSide(expr)) {
  1734. throwError({}, Messages.InvalidLHSInAssignment);
  1735. }
  1736. return delegate.createUnaryExpression(token.value, expr);
  1737. }
  1738. if (match('+') || match('-') || match('~') || match('!')) {
  1739. token = lex();
  1740. expr = parseUnaryExpression();
  1741. return delegate.createUnaryExpression(token.value, expr);
  1742. }
  1743. if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
  1744. token = lex();
  1745. expr = parseUnaryExpression();
  1746. expr = delegate.createUnaryExpression(token.value, expr);
  1747. if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
  1748. throwErrorTolerant({}, Messages.StrictDelete);
  1749. }
  1750. return expr;
  1751. }
  1752. return parsePostfixExpression();
  1753. }
  1754. function binaryPrecedence(token, allowIn) {
  1755. var prec = 0;
  1756. if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
  1757. return 0;
  1758. }
  1759. switch (token.value) {
  1760. case '||':
  1761. prec = 1;
  1762. break;
  1763. case '&&':
  1764. prec = 2;
  1765. break;
  1766. case '|':
  1767. prec = 3;
  1768. break;
  1769. case '^':
  1770. prec = 4;
  1771. break;
  1772. case '&':
  1773. prec = 5;
  1774. break;
  1775. case '==':
  1776. case '!=':
  1777. case '===':
  1778. case '!==':
  1779. prec = 6;
  1780. break;
  1781. case '<':
  1782. case '>':
  1783. case '<=':
  1784. case '>=':
  1785. case 'instanceof':
  1786. prec = 7;
  1787. break;
  1788. case 'in':
  1789. prec = allowIn ? 7 : 0;
  1790. break;
  1791. case '<<':
  1792. case '>>':
  1793. case '>>>':
  1794. prec = 8;
  1795. break;
  1796. case '+':
  1797. case '-':
  1798. prec = 9;
  1799. break;
  1800. case '*':
  1801. case '/':
  1802. case '%':
  1803. prec = 11;
  1804. break;
  1805. default:
  1806. break;
  1807. }
  1808. return prec;
  1809. }
  1810. // 11.5 Multiplicative Operators
  1811. // 11.6 Additive Operators
  1812. // 11.7 Bitwise Shift Operators
  1813. // 11.8 Relational Operators
  1814. // 11.9 Equality Operators
  1815. // 11.10 Binary Bitwise Operators
  1816. // 11.11 Binary Logical Operators
  1817. function parseBinaryExpression() {
  1818. var expr, token, prec, previousAllowIn, stack, right, operator, left, i;
  1819. previousAllowIn = state.allowIn;
  1820. state.allowIn = true;
  1821. expr = parseUnaryExpression();
  1822. token = lookahead;
  1823. prec = binaryPrecedence(token, previousAllowIn);
  1824. if (prec === 0) {
  1825. return expr;
  1826. }
  1827. token.prec = prec;
  1828. lex();
  1829. stack = [expr, token, parseUnaryExpression()];
  1830. while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) {
  1831. // Reduce: make a binary expression from the three topmost entries.
  1832. while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
  1833. right = stack.pop();
  1834. operator = stack.pop().value;
  1835. left = stack.pop();
  1836. stack.push(delegate.createBinaryExpression(operator, left, right));
  1837. }
  1838. // Shift.
  1839. token = lex();
  1840. token.prec = prec;
  1841. stack.push(token);
  1842. stack.push(parseUnaryExpression());
  1843. }
  1844. state.allowIn = previousAllowIn;
  1845. // Final reduce to clean-up the stack.
  1846. i = stack.length - 1;
  1847. expr = stack[i];
  1848. while (i > 1) {
  1849. expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
  1850. i -= 2;
  1851. }
  1852. return expr;
  1853. }
  1854. // 11.12 Conditional Operator
  1855. function parseConditionalExpression() {
  1856. var expr, previousAllowIn, consequent, alternate;
  1857. expr = parseBinaryExpression();
  1858. if (match('?')) {
  1859. lex();
  1860. previousAllowIn = state.allowIn;
  1861. state.allowIn = true;
  1862. consequent = parseAssignmentExpression();
  1863. state.allowIn = previousAllowIn;
  1864. expect(':');
  1865. alternate = parseAssignmentExpression();
  1866. expr = delegate.createConditionalExpression(expr, consequent, alternate);
  1867. }
  1868. return expr;
  1869. }
  1870. // 11.13 Assignment Operators
  1871. function parseAssignmentExpression() {
  1872. var token, left, right;
  1873. token = lookahead;
  1874. left = parseConditionalExpression();
  1875. if (matchAssign()) {
  1876. // LeftHandSideExpression
  1877. if (!isLeftHandSide(left)) {
  1878. throwError({}, Messages.InvalidLHSInAssignment);
  1879. }
  1880. // 11.13.1
  1881. if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) {
  1882. throwErrorTolerant(token, Messages.StrictLHSAssignment);
  1883. }
  1884. token = lex();
  1885. right = parseAssignmentExpression();
  1886. return delegate.createAssignmentExpression(token.value, left, right);
  1887. }
  1888. return left;
  1889. }
  1890. // 11.14 Comma Operator
  1891. function parseExpression() {
  1892. var expr = parseAssignmentExpression();
  1893. if (match(',')) {
  1894. expr = delegate.createSequenceExpression([ expr ]);
  1895. while (index < length) {
  1896. if (!match(',')) {
  1897. break;
  1898. }
  1899. lex();
  1900. expr.expressions.push(parseAssignmentExpression());
  1901. }
  1902. }
  1903. return expr;
  1904. }
  1905. // 12.1 Block
  1906. function parseStatementList() {
  1907. var list = [],
  1908. statement;
  1909. while (index < length) {
  1910. if (match('}')) {
  1911. break;
  1912. }
  1913. statement = parseSourceElement();
  1914. if (typeof statement === 'undefined') {
  1915. break;
  1916. }
  1917. list.push(statement);
  1918. }
  1919. return list;
  1920. }
  1921. function parseBlock() {
  1922. var block;
  1923. expect('{');
  1924. block = parseStatementList();
  1925. expect('}');
  1926. return delegate.createBlockStatement(block);
  1927. }
  1928. // 12.2 Variable Statement
  1929. function parseVariableIdentifier() {
  1930. var token = lex();
  1931. if (token.type !== Token.Identifier) {
  1932. throwUnexpected(token);
  1933. }
  1934. return delegate.createIdentifier(token.value);
  1935. }
  1936. function parseVariableDeclaration(kind) {
  1937. var id = parseVariableIdentifier(),
  1938. init = null;
  1939. // 12.2.1
  1940. if (strict && isRestrictedWord(id.name)) {
  1941. throwErrorTolerant({}, Messages.StrictVarName);
  1942. }
  1943. if (kind === 'const') {
  1944. expect('=');
  1945. init = parseAssignmentExpression();
  1946. } else if (match('=')) {
  1947. lex();
  1948. init = parseAssignmentExpression();
  1949. }
  1950. return delegate.createVariableDeclarator(id, init);
  1951. }
  1952. function parseVariableDeclarationList(kind) {
  1953. var list = [];
  1954. do {
  1955. list.push(parseVariableDeclaration(kind));
  1956. if (!match(',')) {
  1957. break;
  1958. }
  1959. lex();
  1960. } while (index < length);
  1961. return list;
  1962. }
  1963. function parseVariableStatement() {
  1964. var declarations;
  1965. expectKeyword('var');
  1966. declarations = parseVariableDeclarationList();
  1967. consumeSemicolon();
  1968. return delegate.createVariableDeclaration(declarations, 'var');
  1969. }
  1970. // kind may be `const` or `let`
  1971. // Both are experimental and not in the specification yet.
  1972. // see http://wiki.ecmascript.org/doku.php?id=harmony:const
  1973. // and http://wiki.ecmascript.org/doku.php?id=harmony:let
  1974. function parseConstLetDeclaration(kind) {
  1975. var declarations;
  1976. expectKeyword(kind);
  1977. declarations = parseVariableDeclarationList(kind);
  1978. consumeSemicolon();
  1979. return delegate.createVariableDeclaration(declarations, kind);
  1980. }
  1981. // 12.3 Empty Statement
  1982. function parseEmptyStatement() {
  1983. expect(';');
  1984. return delegate.createEmptyStatement();
  1985. }
  1986. // 12.4 Expression Statement
  1987. function parseExpressionStatement() {
  1988. var expr = parseExpression();
  1989. consumeSemicolon();
  1990. return delegate.createExpressionStatement(expr);
  1991. }
  1992. // 12.5 If statement
  1993. function parseIfStatement() {
  1994. var test, consequent, alternate;
  1995. expectKeyword('if');
  1996. expect('(');
  1997. test = parseExpression();
  1998. expect(')');
  1999. consequent = parseStatement();
  2000. if (matchKeyword('else')) {
  2001. lex();
  2002. alternate = parseStatement();
  2003. } else {
  2004. alternate = null;
  2005. }
  2006. return delegate.createIfStatement(test, consequent, alternate);
  2007. }
  2008. // 12.6 Iteration Statements
  2009. function parseDoWhileStatement() {
  2010. var body, test, oldInIteration;
  2011. expectKeyword('do');
  2012. oldInIteration = state.inIteration;
  2013. state.inIteration = true;
  2014. body = parseStatement();
  2015. state.inIteration = oldInIteration;
  2016. expectKeyword('while');
  2017. expect('(');
  2018. test = parseExpression();
  2019. expect(')');
  2020. if (match(';')) {
  2021. lex();
  2022. }
  2023. return delegate.createDoWhileStatement(body, test);
  2024. }
  2025. function parseWhileStatement() {
  2026. var test, body, oldInIteration;
  2027. expectKeyword('while');
  2028. expect('(');
  2029. test = parseExpression();
  2030. expect(')');
  2031. oldInIteration = state.inIteration;
  2032. state.inIteration = true;
  2033. body = parseStatement();
  2034. state.inIteration = oldInIteration;
  2035. return delegate.createWhileStatement(test, body);
  2036. }
  2037. function parseForVariableDeclaration() {
  2038. var token = lex(),
  2039. declarations = parseVariableDeclarationList();
  2040. return delegate.createVariableDeclaration(declarations, token.value);
  2041. }
  2042. function parseForStatement() {
  2043. var init, test, update, left, right, body, oldInIteration;
  2044. init = test = update = null;
  2045. expectKeyword('for');
  2046. expect('(');
  2047. if (match(';')) {
  2048. lex();
  2049. } else {
  2050. if (matchKeyword('var') || matchKeyword('let')) {
  2051. state.allowIn = false;
  2052. init = parseForVariableDeclaration();
  2053. state.allowIn = true;
  2054. if (init.declarations.length === 1 && matchKeyword('in')) {
  2055. lex();
  2056. left = init;
  2057. right = parseExpression();
  2058. init = null;
  2059. }
  2060. } else {
  2061. state.allowIn = false;
  2062. init = parseExpression();
  2063. state.allowIn = true;
  2064. if (matchKeyword('in')) {
  2065. // LeftHandSideExpression
  2066. if (!isLeftHandSide(init)) {
  2067. throwError({}, Messages.InvalidLHSInForIn);
  2068. }
  2069. lex();
  2070. left = init;
  2071. right = parseExpression();
  2072. init = null;
  2073. }
  2074. }
  2075. if (typeof left === 'undefined') {
  2076. expect(';');
  2077. }
  2078. }
  2079. if (typeof left === 'undefined') {
  2080. if (!match(';')) {
  2081. test = parseExpression();
  2082. }
  2083. expect(';');
  2084. if (!match(')')) {
  2085. update = parseExpression();
  2086. }
  2087. }
  2088. expect(')');
  2089. oldInIteration = state.inIteration;
  2090. state.inIteration = true;
  2091. body = parseStatement();
  2092. state.inIteration = oldInIteration;
  2093. return (typeof left === 'undefined') ?
  2094. delegate.createForStatement(init, test, update, body) :
  2095. delegate.createForInStatement(left, right, body);
  2096. }
  2097. // 12.7 The continue statement
  2098. function parseContinueStatement() {
  2099. var label = null, key;
  2100. expectKeyword('continue');
  2101. // Optimize the most common form: 'continue;'.
  2102. if (source.charCodeAt(index) === 59) {
  2103. lex();
  2104. if (!state.inIteration) {
  2105. throwError({}, Messages.IllegalContinue);
  2106. }
  2107. return delegate.createContinueStatement(null);
  2108. }
  2109. if (peekLineTerminator()) {
  2110. if (!state.inIteration) {
  2111. throwError({}, Messages.IllegalContinue);
  2112. }
  2113. return delegate.createContinueStatement(null);
  2114. }
  2115. if (lookahead.type === Token.Identifier) {
  2116. label = parseVariableIdentifier();
  2117. key = '$' + label.name;
  2118. if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
  2119. throwError({}, Messages.UnknownLabel, label.name);
  2120. }
  2121. }
  2122. consumeSemicolon();
  2123. if (label === null && !state.inIteration) {
  2124. throwError({}, Messages.IllegalContinue);
  2125. }
  2126. return delegate.createContinueStatement(label);
  2127. }
  2128. // 12.8 The break statement
  2129. function parseBreakStatement() {
  2130. var label = null, key;
  2131. expectKeyword('break');
  2132. // Catch the very common case first: immediately a semicolon (char #59).
  2133. if (source.charCodeAt(index) === 59) {
  2134. lex();
  2135. if (!(state.inIteration || state.inSwitch)) {
  2136. throwError({}, Messages.IllegalBreak);
  2137. }
  2138. return delegate.createBreakStatement(null);
  2139. }
  2140. if (peekLineTerminator()) {
  2141. if (!(state.inIteration || state.inSwitch)) {
  2142. throwError({}, Messages.IllegalBreak);
  2143. }
  2144. return delegate.createBreakStatement(null);
  2145. }
  2146. if (lookahead.type === Token.Identifier) {
  2147. label = parseVariableIdentifier();
  2148. key = '$' + label.name;
  2149. if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
  2150. throwError({}, Messages.UnknownLabel, label.name);
  2151. }
  2152. }
  2153. consumeSemicolon();
  2154. if (label === null && !(state.inIteration || state.inSwitch)) {
  2155. throwError({}, Messages.IllegalBreak);
  2156. }
  2157. return delegate.createBreakStatement(label);
  2158. }
  2159. // 12.9 The return statement
  2160. function parseReturnStatement() {
  2161. var argument = null;
  2162. expectKeyword('return');
  2163. if (!state.inFunctionBody) {
  2164. throwErrorTolerant({}, Messages.IllegalReturn);
  2165. }
  2166. // 'return' followed by a space and an identifier is very common.
  2167. if (source.charCodeAt(index) === 32) {
  2168. if (isIdentifierStart(source.charCodeAt(index + 1))) {
  2169. argument = parseExpression();
  2170. consumeSemicolon();
  2171. return delegate.createReturnStatement(argument);
  2172. }
  2173. }
  2174. if (peekLineTerminator()) {
  2175. return delegate.createReturnStatement(null);
  2176. }
  2177. if (!match(';')) {
  2178. if (!match('}') && lookahead.type !== Token.EOF) {
  2179. argument = parseExpression();
  2180. }
  2181. }
  2182. consumeSemicolon();
  2183. return delegate.createReturnStatement(argument);
  2184. }
  2185. // 12.10 The with statement
  2186. function parseWithStatement() {
  2187. var object, body;
  2188. if (strict) {
  2189. throwErrorTolerant({}, Messages.StrictModeWith);
  2190. }
  2191. expectKeyword('with');
  2192. expect('(');
  2193. object = parseExpression();
  2194. expect(')');
  2195. body = parseStatement();
  2196. return delegate.createWithStatement(object, body);
  2197. }
  2198. // 12.10 The swith statement
  2199. function parseSwitchCase() {
  2200. var test,
  2201. consequent = [],
  2202. statement;
  2203. if (matchKeyword('default')) {
  2204. lex();
  2205. test = null;
  2206. } else {
  2207. expectKeyword('case');
  2208. test = parseExpression();
  2209. }
  2210. expect(':');
  2211. while (index < length) {
  2212. if (match('}') || matchKeyword('default') || matchKeyword('case')) {
  2213. break;
  2214. }
  2215. statement = parseStatement();
  2216. consequent.push(statement);
  2217. }
  2218. return delegate.createSwitchCase(test, consequent);
  2219. }
  2220. function parseSwitchStatement() {
  2221. var discriminant, cases, clause, oldInSwitch, defaultFound;
  2222. expectKeyword('switch');
  2223. expect('(');
  2224. discriminant = parseExpression();
  2225. expect(')');
  2226. expect('{');
  2227. if (match('}')) {
  2228. lex();
  2229. return delegate.createSwitchStatement(discriminant);
  2230. }
  2231. cases = [];
  2232. oldInSwitch = state.inSwitch;
  2233. state.inSwitch = true;
  2234. defaultFound = false;
  2235. while (index < length) {
  2236. if (match('}')) {
  2237. break;
  2238. }
  2239. clause = parseSwitchCase();
  2240. if (clause.test === null) {
  2241. if (defaultFound) {
  2242. throwError({}, Messages.MultipleDefaultsInSwitch);
  2243. }
  2244. defaultFound = true;
  2245. }
  2246. cases.push(clause);
  2247. }
  2248. state.inSwitch = oldInSwitch;
  2249. expect('}');
  2250. return delegate.createSwitchStatement(discriminant, cases);
  2251. }
  2252. // 12.13 The throw statement
  2253. function parseThrowStatement() {
  2254. var argument;
  2255. expectKeyword('throw');
  2256. if (peekLineTerminator()) {
  2257. throwError({}, Messages.NewlineAfterThrow);
  2258. }
  2259. argument = parseExpression();
  2260. consumeSemicolon();
  2261. return delegate.createThrowStatement(argument);
  2262. }
  2263. // 12.14 The try statement
  2264. function parseCatchClause() {
  2265. var param, body;
  2266. expectKeyword('catch');
  2267. expect('(');
  2268. if (match(')')) {
  2269. throwUnexpected(lookahead);
  2270. }
  2271. param = parseExpression();
  2272. // 12.14.1
  2273. if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) {
  2274. throwErrorTolerant({}, Messages.StrictCatchVariable);
  2275. }
  2276. expect(')');
  2277. body = parseBlock();
  2278. return delegate.createCatchClause(param, body);
  2279. }
  2280. function parseTryStatement() {
  2281. var block, handlers = [], finalizer = null;
  2282. expectKeyword('try');
  2283. block = parseBlock();
  2284. if (matchKeyword('catch')) {
  2285. handlers.push(parseCatchClause());
  2286. }
  2287. if (matchKeyword('finally')) {
  2288. lex();
  2289. finalizer = parseBlock();
  2290. }
  2291. if (handlers.length === 0 && !finalizer) {
  2292. throwError({}, Messages.NoCatchOrFinally);
  2293. }
  2294. return delegate.createTryStatement(block, [], handlers, finalizer);
  2295. }
  2296. // 12.15 The debugger statement
  2297. function parseDebuggerStatement() {
  2298. expectKeyword('debugger');
  2299. consumeSemicolon();
  2300. return delegate.createDebuggerStatement();
  2301. }
  2302. // 12 Statements
  2303. function parseStatement() {
  2304. var type = lookahead.type,
  2305. expr,
  2306. labeledBody,
  2307. key;
  2308. if (type === Token.EOF) {
  2309. throwUnexpected(lookahead);
  2310. }
  2311. if (type === Token.Punctuator) {
  2312. switch (lookahead.value) {
  2313. case ';':
  2314. return parseEmptyStatement();
  2315. case '{':
  2316. return parseBlock();
  2317. case '(':
  2318. return parseExpressionStatement();
  2319. default:
  2320. break;
  2321. }
  2322. }
  2323. if (type === Token.Keyword) {
  2324. switch (lookahead.value) {
  2325. case 'break':
  2326. return parseBreakStatement();
  2327. case 'continue':
  2328. return parseContinueStatement();
  2329. case 'debugger':
  2330. return parseDebuggerStatement();
  2331. case 'do':
  2332. return parseDoWhileStatement();
  2333. case 'for':
  2334. return parseForStatement();
  2335. case 'function':
  2336. return parseFunctionDeclaration();
  2337. case 'if':
  2338. return parseIfStatement();
  2339. case 'return':
  2340. return parseReturnStatement();
  2341. case 'switch':
  2342. return parseSwitchStatement();
  2343. case 'throw':
  2344. return parseThrowStatement();
  2345. case 'try':
  2346. return parseTryStatement();
  2347. case 'var':
  2348. return parseVariableStatement();
  2349. case 'while':
  2350. return parseWhileStatement();
  2351. case 'with':
  2352. return parseWithStatement();
  2353. default:
  2354. break;
  2355. }
  2356. }
  2357. expr = parseExpression();
  2358. // 12.12 Labelled Statements
  2359. if ((expr.type === Syntax.Identifier) && match(':')) {
  2360. lex();
  2361. key = '$' + expr.name;
  2362. if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
  2363. throwError({}, Messages.Redeclaration, 'Label', expr.name);
  2364. }
  2365. state.labelSet[key] = true;
  2366. labeledBody = parseStatement();
  2367. delete state.labelSet[key];
  2368. return delegate.createLabeledStatement(expr, labeledBody);
  2369. }
  2370. consumeSemicolon();
  2371. return delegate.createExpressionStatement(expr);
  2372. }
  2373. // 13 Function Definition
  2374. function parseFunctionSourceElements() {
  2375. var sourceElement, sourceElements = [], token, directive, firstRestricted,
  2376. oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
  2377. expect('{');
  2378. while (index < length) {
  2379. if (lookahead.type !== Token.StringLiteral) {
  2380. break;
  2381. }
  2382. token = lookahead;
  2383. sourceElement = parseSourceElement();
  2384. sourceElements.push(sourceElement);
  2385. if (sourceElement.expression.type !== Syntax.Literal) {
  2386. // this is not directive
  2387. break;
  2388. }
  2389. directive = source.slice(token.range[0] + 1, token.range[1] - 1);
  2390. if (directive === 'use strict') {
  2391. strict = true;
  2392. if (firstRestricted) {
  2393. throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
  2394. }
  2395. } else {
  2396. if (!firstRestricted && token.octal) {
  2397. firstRestricted = token;
  2398. }
  2399. }
  2400. }
  2401. oldLabelSet = state.labelSet;
  2402. oldInIteration = state.inIteration;
  2403. oldInSwitch = state.inSwitch;
  2404. oldInFunctionBody = state.inFunctionBody;
  2405. state.labelSet = {};
  2406. state.inIteration = false;
  2407. state.inSwitch = false;
  2408. state.inFunctionBody = true;
  2409. while (index < length) {
  2410. if (match('}')) {
  2411. break;
  2412. }
  2413. sourceElement = parseSourceElement();
  2414. if (typeof sourceElement === 'undefined') {
  2415. break;
  2416. }
  2417. sourceElements.push(sourceElement);
  2418. }
  2419. expect('}');
  2420. state.labelSet = oldLabelSet;
  2421. state.inIteration = oldInIteration;
  2422. state.inSwitch = oldInSwitch;
  2423. state.inFunctionBody = oldInFunctionBody;
  2424. return delegate.createBlockStatement(sourceElements);
  2425. }
  2426. function parseParams(firstRestricted) {
  2427. var param, params = [], token, stricted, paramSet, key, message;
  2428. expect('(');
  2429. if (!match(')')) {
  2430. paramSet = {};
  2431. while (index < length) {
  2432. token = lookahead;
  2433. param = parseVariableIdentifier();
  2434. key = '$' + token.value;
  2435. if (strict) {
  2436. if (isRestrictedWord(token.value)) {
  2437. stricted = token;
  2438. message = Messages.StrictParamName;
  2439. }
  2440. if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
  2441. stricted = token;
  2442. message = Messages.StrictParamDupe;
  2443. }
  2444. } else if (!firstRestricted) {
  2445. if (isRestrictedWord(token.value)) {
  2446. firstRestricted = token;
  2447. message = Messages.StrictParamName;
  2448. } else if (isStrictModeReservedWord(token.value)) {
  2449. firstRestricted = token;
  2450. message = Messages.StrictReservedWord;
  2451. } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
  2452. firstRestricted = token;
  2453. message = Messages.StrictParamDupe;
  2454. }
  2455. }
  2456. params.push(param);
  2457. paramSet[key] = true;
  2458. if (match(')')) {
  2459. break;
  2460. }
  2461. expect(',');
  2462. }
  2463. }
  2464. expect(')');
  2465. return {
  2466. params: params,
  2467. stricted: stricted,
  2468. firstRestricted: firstRestricted,
  2469. message: message
  2470. };
  2471. }
  2472. function parseFunctionDeclaration() {
  2473. var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict;
  2474. expectKeyword('function');
  2475. token = lookahead;
  2476. id = parseVariableIdentifier();
  2477. if (strict) {
  2478. if (isRestrictedWord(token.value)) {
  2479. throwErrorTolerant(token, Messages.StrictFunctionName);
  2480. }
  2481. } else {
  2482. if (isRestrictedWord(token.value)) {
  2483. firstRestricted = token;
  2484. message = Messages.StrictFunctionName;
  2485. } else if (isStrictModeReservedWord(token.value)) {
  2486. firstRestricted = token;
  2487. message = Messages.StrictReservedWord;
  2488. }
  2489. }
  2490. tmp = parseParams(firstRestricted);
  2491. params = tmp.params;
  2492. stricted = tmp.stricted;
  2493. firstRestricted = tmp.firstRestricted;
  2494. if (tmp.message) {
  2495. message = tmp.message;
  2496. }
  2497. previousStrict = strict;
  2498. body = parseFunctionSourceElements();
  2499. if (strict && firstRestricted) {
  2500. throwError(firstRestricted, message);
  2501. }
  2502. if (strict && stricted) {
  2503. throwErrorTolerant(stricted, message);
  2504. }
  2505. strict = previousStrict;
  2506. return delegate.createFunctionDeclaration(id, params, [], body);
  2507. }
  2508. function parseFunctionExpression() {
  2509. var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict;
  2510. expectKeyword('function');
  2511. if (!match('(')) {
  2512. token = lookahead;
  2513. id = parseVariableIdentifier();
  2514. if (strict) {
  2515. if (isRestrictedWord(token.value)) {
  2516. throwErrorTolerant(token, Messages.StrictFunctionName);
  2517. }
  2518. } else {
  2519. if (isRestrictedWord(token.value)) {
  2520. firstRestricted = token;
  2521. message = Messages.StrictFunctionName;
  2522. } else if (isStrictModeReservedWord(token.value)) {
  2523. firstRestricted = token;
  2524. message = Messages.StrictReservedWord;
  2525. }
  2526. }
  2527. }
  2528. tmp = parseParams(firstRestricted);
  2529. params = tmp.params;
  2530. stricted = tmp.stricted;
  2531. firstRestricted = tmp.firstRestricted;
  2532. if (tmp.message) {
  2533. message = tmp.message;
  2534. }
  2535. previousStrict = strict;
  2536. body = parseFunctionSourceElements();
  2537. if (strict && firstRestricted) {
  2538. throwError(firstRestricted, message);
  2539. }
  2540. if (strict && stricted) {
  2541. throwErrorTolerant(stricted, message);
  2542. }
  2543. strict = previousStrict;
  2544. return delegate.createFunctionExpression(id, params, [], body);
  2545. }
  2546. // 14 Program
  2547. function parseSourceElement() {
  2548. if (lookahead.type === Token.Keyword) {
  2549. switch (lookahead.value) {
  2550. case 'const':
  2551. case 'let':
  2552. return parseConstLetDeclaration(lookahead.value);
  2553. case 'function':
  2554. return parseFunctionDeclaration();
  2555. default:
  2556. return parseStatement();
  2557. }
  2558. }
  2559. if (lookahead.type !== Token.EOF) {
  2560. return parseStatement();
  2561. }
  2562. }
  2563. function parseSourceElements() {
  2564. var sourceElement, sourceElements = [], token, directive, firstRestricted;
  2565. while (index < length) {
  2566. token = lookahead;
  2567. if (token.type !== Token.StringLiteral) {
  2568. break;
  2569. }
  2570. sourceElement = parseSourceElement();
  2571. sourceElements.push(sourceElement);
  2572. if (sourceElement.expression.type !== Syntax.Literal) {
  2573. // this is not directive
  2574. break;
  2575. }
  2576. directive = source.slice(token.range[0] + 1, token.range[1] - 1);
  2577. if (directive === 'use strict') {
  2578. strict = true;
  2579. if (firstRestricted) {
  2580. throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
  2581. }
  2582. } else {
  2583. if (!firstRestricted && token.octal) {
  2584. firstRestricted = token;
  2585. }
  2586. }
  2587. }
  2588. while (index < length) {
  2589. sourceElement = parseSourceElement();
  2590. if (typeof sourceElement === 'undefined') {
  2591. break;
  2592. }
  2593. sourceElements.push(sourceElement);
  2594. }
  2595. return sourceElements;
  2596. }
  2597. function parseProgram() {
  2598. var body;
  2599. strict = false;
  2600. peek();
  2601. body = parseSourceElements();
  2602. return delegate.createProgram(body);
  2603. }
  2604. // The following functions are needed only when the option to preserve
  2605. // the comments is active.
  2606. function addComment(type, value, start, end, loc) {
  2607. assert(typeof start === 'number', 'Comment must have valid position');
  2608. // Because the way the actual token is scanned, often the comments
  2609. // (if any) are skipped twice during the lexical analysis.
  2610. // Thus, we need to skip adding a comment if the comment array already
  2611. // handled it.
  2612. if (extra.comments.length > 0) {
  2613. if (extra.comments[extra.comments.length - 1].range[1] > start) {
  2614. return;
  2615. }
  2616. }
  2617. extra.comments.push({
  2618. type: type,
  2619. value: value,
  2620. range: [start, end],
  2621. loc: loc
  2622. });
  2623. }
  2624. function scanComment() {
  2625. var comment, ch, loc, start, blockComment, lineComment;
  2626. comment = '';
  2627. blockComment = false;
  2628. lineComment = false;
  2629. while (index < length) {
  2630. ch = source[index];
  2631. if (lineComment) {
  2632. ch = source[index++];
  2633. if (isLineTerminator(ch.charCodeAt(0))) {
  2634. loc.end = {
  2635. line: lineNumber,
  2636. column: index - lineStart - 1
  2637. };
  2638. lineComment = false;
  2639. addComment('Line', comment, start, index - 1, loc);
  2640. if (ch === '\r' && source[index] === '\n') {
  2641. ++index;
  2642. }
  2643. ++lineNumber;
  2644. lineStart = index;
  2645. comment = '';
  2646. } else if (index >= length) {
  2647. lineComment = false;
  2648. comment += ch;
  2649. loc.end = {
  2650. line: lineNumber,
  2651. column: length - lineStart
  2652. };
  2653. addComment('Line', comment, start, length, loc);
  2654. } else {
  2655. comment += ch;
  2656. }
  2657. } else if (blockComment) {
  2658. if (isLineTerminator(ch.charCodeAt(0))) {
  2659. if (ch === '\r' && source[index + 1] === '\n') {
  2660. ++index;
  2661. comment += '\r\n';
  2662. } else {
  2663. comment += ch;
  2664. }
  2665. ++lineNumber;
  2666. ++index;
  2667. lineStart = index;
  2668. if (index >= length) {
  2669. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  2670. }
  2671. } else {
  2672. ch = source[index++];
  2673. if (index >= length) {
  2674. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  2675. }
  2676. comment += ch;
  2677. if (ch === '*') {
  2678. ch = source[index];
  2679. if (ch === '/') {
  2680. comment = comment.substr(0, comment.length - 1);
  2681. blockComment = false;
  2682. ++index;
  2683. loc.end = {
  2684. line: lineNumber,
  2685. column: index - lineStart
  2686. };
  2687. addComment('Block', comment, start, index, loc);
  2688. comment = '';
  2689. }
  2690. }
  2691. }
  2692. } else if (ch === '/') {
  2693. ch = source[index + 1];
  2694. if (ch === '/') {
  2695. loc = {
  2696. start: {
  2697. line: lineNumber,
  2698. column: index - lineStart
  2699. }
  2700. };
  2701. start = index;
  2702. index += 2;
  2703. lineComment = true;
  2704. if (index >= length) {
  2705. loc.end = {
  2706. line: lineNumber,
  2707. column: index - lineStart
  2708. };
  2709. lineComment = false;
  2710. addComment('Line', comment, start, index, loc);
  2711. }
  2712. } else if (ch === '*') {
  2713. start = index;
  2714. index += 2;
  2715. blockComment = true;
  2716. loc = {
  2717. start: {
  2718. line: lineNumber,
  2719. column: index - lineStart - 2
  2720. }
  2721. };
  2722. if (index >= length) {
  2723. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  2724. }
  2725. } else {
  2726. break;
  2727. }
  2728. } else if (isWhiteSpace(ch.charCodeAt(0))) {
  2729. ++index;
  2730. } else if (isLineTerminator(ch.charCodeAt(0))) {
  2731. ++index;
  2732. if (ch === '\r' && source[index] === '\n') {
  2733. ++index;
  2734. }
  2735. ++lineNumber;
  2736. lineStart = index;
  2737. } else {
  2738. break;
  2739. }
  2740. }
  2741. }
  2742. function filterCommentLocation() {
  2743. var i, entry, comment, comments = [];
  2744. for (i = 0; i < extra.comments.length; ++i) {
  2745. entry = extra.comments[i];
  2746. comment = {
  2747. type: entry.type,
  2748. value: entry.value
  2749. };
  2750. if (extra.range) {
  2751. comment.range = entry.range;
  2752. }
  2753. if (extra.loc) {
  2754. comment.loc = entry.loc;
  2755. }
  2756. comments.push(comment);
  2757. }
  2758. extra.comments = comments;
  2759. }
  2760. function collectToken() {
  2761. var start, loc, token, range, value;
  2762. skipComment();
  2763. start = index;
  2764. loc = {
  2765. start: {
  2766. line: lineNumber,
  2767. column: index - lineStart
  2768. }
  2769. };
  2770. token = extra.advance();
  2771. loc.end = {
  2772. line: lineNumber,
  2773. column: index - lineStart
  2774. };
  2775. if (token.type !== Token.EOF) {
  2776. range = [token.range[0], token.range[1]];
  2777. value = source.slice(token.range[0], token.range[1]);
  2778. extra.tokens.push({
  2779. type: TokenName[token.type],
  2780. value: value,
  2781. range: range,
  2782. loc: loc
  2783. });
  2784. }
  2785. return token;
  2786. }
  2787. function collectRegex() {
  2788. var pos, loc, regex, token;
  2789. skipComment();
  2790. pos = index;
  2791. loc = {
  2792. start: {
  2793. line: lineNumber,
  2794. column: index - lineStart
  2795. }
  2796. };
  2797. regex = extra.scanRegExp();
  2798. loc.end = {
  2799. line: lineNumber,
  2800. column: index - lineStart
  2801. };
  2802. if (!extra.tokenize) {
  2803. // Pop the previous token, which is likely '/' or '/='
  2804. if (extra.tokens.length > 0) {
  2805. token = extra.tokens[extra.tokens.length - 1];
  2806. if (token.range[0] === pos && token.type === 'Punctuator') {
  2807. if (token.value === '/' || token.value === '/=') {
  2808. extra.tokens.pop();
  2809. }
  2810. }
  2811. }
  2812. extra.tokens.push({
  2813. type: 'RegularExpression',
  2814. value: regex.literal,
  2815. range: [pos, index],
  2816. loc: loc
  2817. });
  2818. }
  2819. return regex;
  2820. }
  2821. function filterTokenLocation() {
  2822. var i, entry, token, tokens = [];
  2823. for (i = 0; i < extra.tokens.length; ++i) {
  2824. entry = extra.tokens[i];
  2825. token = {
  2826. type: entry.type,
  2827. value: entry.value
  2828. };
  2829. if (extra.range) {
  2830. token.range = entry.range;
  2831. }
  2832. if (extra.loc) {
  2833. token.loc = entry.loc;
  2834. }
  2835. tokens.push(token);
  2836. }
  2837. extra.tokens = tokens;
  2838. }
  2839. function createLocationMarker() {
  2840. var marker = {};
  2841. marker.range = [index, index];
  2842. marker.loc = {
  2843. start: {
  2844. line: lineNumber,
  2845. column: index - lineStart
  2846. },
  2847. end: {
  2848. line: lineNumber,
  2849. column: index - lineStart
  2850. }
  2851. };
  2852. marker.end = function () {
  2853. this.range[1] = index;
  2854. this.loc.end.line = lineNumber;
  2855. this.loc.end.column = index - lineStart;
  2856. };
  2857. marker.applyGroup = function (node) {
  2858. if (extra.range) {
  2859. node.groupRange = [this.range[0], this.range[1]];
  2860. }
  2861. if (extra.loc) {
  2862. node.groupLoc = {
  2863. start: {
  2864. line: this.loc.start.line,
  2865. column: this.loc.start.column
  2866. },
  2867. end: {
  2868. line: this.loc.end.line,
  2869. column: this.loc.end.column
  2870. }
  2871. };
  2872. node = delegate.postProcess(node);
  2873. }
  2874. };
  2875. marker.apply = function (node) {
  2876. if (extra.range) {
  2877. node.range = [this.range[0], this.range[1]];
  2878. }
  2879. if (extra.loc) {
  2880. node.loc = {
  2881. start: {
  2882. line: this.loc.start.line,
  2883. column: this.loc.start.column
  2884. },
  2885. end: {
  2886. line: this.loc.end.line,
  2887. column: this.loc.end.column
  2888. }
  2889. };
  2890. node = delegate.postProcess(node);
  2891. }
  2892. };
  2893. return marker;
  2894. }
  2895. function trackGroupExpression() {
  2896. var marker, expr;
  2897. skipComment();
  2898. marker = createLocationMarker();
  2899. expect('(');
  2900. expr = parseExpression();
  2901. expect(')');
  2902. marker.end();
  2903. marker.applyGroup(expr);
  2904. return expr;
  2905. }
  2906. function trackLeftHandSideExpression() {
  2907. var marker, expr, property;
  2908. skipComment();
  2909. marker = createLocationMarker();
  2910. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  2911. while (match('.') || match('[')) {
  2912. if (match('[')) {
  2913. property = parseComputedMember();
  2914. expr = delegate.createMemberExpression('[', expr, property);
  2915. marker.end();
  2916. marker.apply(expr);
  2917. } else {
  2918. property = parseNonComputedMember();
  2919. expr = delegate.createMemberExpression('.', expr, property);
  2920. marker.end();
  2921. marker.apply(expr);
  2922. }
  2923. }
  2924. return expr;
  2925. }
  2926. function trackLeftHandSideExpressionAllowCall() {
  2927. var marker, expr, args, property;
  2928. skipComment();
  2929. marker = createLocationMarker();
  2930. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  2931. while (match('.') || match('[') || match('(')) {
  2932. if (match('(')) {
  2933. args = parseArguments();
  2934. expr = delegate.createCallExpression(expr, args);
  2935. marker.end();
  2936. marker.apply(expr);
  2937. } else if (match('[')) {
  2938. property = parseComputedMember();
  2939. expr = delegate.createMemberExpression('[', expr, property);
  2940. marker.end();
  2941. marker.apply(expr);
  2942. } else {
  2943. property = parseNonComputedMember();
  2944. expr = delegate.createMemberExpression('.', expr, property);
  2945. marker.end();
  2946. marker.apply(expr);
  2947. }
  2948. }
  2949. return expr;
  2950. }
  2951. function filterGroup(node) {
  2952. var n, i, entry;
  2953. n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {};
  2954. for (i in node) {
  2955. if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') {
  2956. entry = node[i];
  2957. if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) {
  2958. n[i] = entry;
  2959. } else {
  2960. n[i] = filterGroup(entry);
  2961. }
  2962. }
  2963. }
  2964. return n;
  2965. }
  2966. function wrapTrackingFunction(range, loc) {
  2967. return function (parseFunction) {
  2968. function isBinary(node) {
  2969. return node.type === Syntax.LogicalExpression ||
  2970. node.type === Syntax.BinaryExpression;
  2971. }
  2972. function visit(node) {
  2973. var start, end;
  2974. if (isBinary(node.left)) {
  2975. visit(node.left);
  2976. }
  2977. if (isBinary(node.right)) {
  2978. visit(node.right);
  2979. }
  2980. if (range) {
  2981. if (node.left.groupRange || node.right.groupRange) {
  2982. start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0];
  2983. end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1];
  2984. node.range = [start, end];
  2985. } else if (typeof node.range === 'undefined') {
  2986. start = node.left.range[0];
  2987. end = node.right.range[1];
  2988. node.range = [start, end];
  2989. }
  2990. }
  2991. if (loc) {
  2992. if (node.left.groupLoc || node.right.groupLoc) {
  2993. start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start;
  2994. end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end;
  2995. node.loc = {
  2996. start: start,
  2997. end: end
  2998. };
  2999. node = delegate.postProcess(node);
  3000. } else if (typeof node.loc === 'undefined') {
  3001. node.loc = {
  3002. start: node.left.loc.start,
  3003. end: node.right.loc.end
  3004. };
  3005. node = delegate.postProcess(node);
  3006. }
  3007. }
  3008. }
  3009. return function () {
  3010. var marker, node;
  3011. skipComment();
  3012. marker = createLocationMarker();
  3013. node = parseFunction.apply(null, arguments);
  3014. marker.end();
  3015. if (range && typeof node.range === 'undefined') {
  3016. marker.apply(node);
  3017. }
  3018. if (loc && typeof node.loc === 'undefined') {
  3019. marker.apply(node);
  3020. }
  3021. if (isBinary(node)) {
  3022. visit(node);
  3023. }
  3024. return node;
  3025. };
  3026. };
  3027. }
  3028. function patch() {
  3029. var wrapTracking;
  3030. if (extra.comments) {
  3031. extra.skipComment = skipComment;
  3032. skipComment = scanComment;
  3033. }
  3034. if (extra.range || extra.loc) {
  3035. extra.parseGroupExpression = parseGroupExpression;
  3036. extra.parseLeftHandSideExpression = parseLeftHandSideExpression;
  3037. extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;
  3038. parseGroupExpression = trackGroupExpression;
  3039. parseLeftHandSideExpression = trackLeftHandSideExpression;
  3040. parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall;
  3041. wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
  3042. extra.parseAssignmentExpression = parseAssignmentExpression;
  3043. extra.parseBinaryExpression = parseBinaryExpression;
  3044. extra.parseBlock = parseBlock;
  3045. extra.parseFunctionSourceElements = parseFunctionSourceElements;
  3046. extra.parseCatchClause = parseCatchClause;
  3047. extra.parseComputedMember = parseComputedMember;
  3048. extra.parseConditionalExpression = parseConditionalExpression;
  3049. extra.parseConstLetDeclaration = parseConstLetDeclaration;
  3050. extra.parseExpression = parseExpression;
  3051. extra.parseForVariableDeclaration = parseForVariableDeclaration;
  3052. extra.parseFunctionDeclaration = parseFunctionDeclaration;
  3053. extra.parseFunctionExpression = parseFunctionExpression;
  3054. extra.parseNewExpression = parseNewExpression;
  3055. extra.parseNonComputedProperty = parseNonComputedProperty;
  3056. extra.parseObjectProperty = parseObjectProperty;
  3057. extra.parseObjectPropertyKey = parseObjectPropertyKey;
  3058. extra.parsePostfixExpression = parsePostfixExpression;
  3059. extra.parsePrimaryExpression = parsePrimaryExpression;
  3060. extra.parseProgram = parseProgram;
  3061. extra.parsePropertyFunction = parsePropertyFunction;
  3062. extra.parseStatement = parseStatement;
  3063. extra.parseSwitchCase = parseSwitchCase;
  3064. extra.parseUnaryExpression = parseUnaryExpression;
  3065. extra.parseVariableDeclaration = parseVariableDeclaration;
  3066. extra.parseVariableIdentifier = parseVariableIdentifier;
  3067. parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
  3068. parseBinaryExpression = wrapTracking(extra.parseBinaryExpression);
  3069. parseBlock = wrapTracking(extra.parseBlock);
  3070. parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
  3071. parseCatchClause = wrapTracking(extra.parseCatchClause);
  3072. parseComputedMember = wrapTracking(extra.parseComputedMember);
  3073. parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
  3074. parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);
  3075. parseExpression = wrapTracking(extra.parseExpression);
  3076. parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
  3077. parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
  3078. parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
  3079. parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression);
  3080. parseNewExpression = wrapTracking(extra.parseNewExpression);
  3081. parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
  3082. parseObjectProperty = wrapTracking(extra.parseObjectProperty);
  3083. parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
  3084. parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);
  3085. parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);
  3086. parseProgram = wrapTracking(extra.parseProgram);
  3087. parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);
  3088. parseStatement = wrapTracking(extra.parseStatement);
  3089. parseSwitchCase = wrapTracking(extra.parseSwitchCase);
  3090. parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);
  3091. parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);
  3092. parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);
  3093. }
  3094. if (typeof extra.tokens !== 'undefined') {
  3095. extra.advance = advance;
  3096. extra.scanRegExp = scanRegExp;
  3097. advance = collectToken;
  3098. scanRegExp = collectRegex;
  3099. }
  3100. }
  3101. function unpatch() {
  3102. if (typeof extra.skipComment === 'function') {
  3103. skipComment = extra.skipComment;
  3104. }
  3105. if (extra.range || extra.loc) {
  3106. parseAssignmentExpression = extra.parseAssignmentExpression;
  3107. parseBinaryExpression = extra.parseBinaryExpression;
  3108. parseBlock = extra.parseBlock;
  3109. parseFunctionSourceElements = extra.parseFunctionSourceElements;
  3110. parseCatchClause = extra.parseCatchClause;
  3111. parseComputedMember = extra.parseComputedMember;
  3112. parseConditionalExpression = extra.parseConditionalExpression;
  3113. parseConstLetDeclaration = extra.parseConstLetDeclaration;
  3114. parseExpression = extra.parseExpression;
  3115. parseForVariableDeclaration = extra.parseForVariableDeclaration;
  3116. parseFunctionDeclaration = extra.parseFunctionDeclaration;
  3117. parseFunctionExpression = extra.parseFunctionExpression;
  3118. parseGroupExpression = extra.parseGroupExpression;
  3119. parseLeftHandSideExpression = extra.parseLeftHandSideExpression;
  3120. parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall;
  3121. parseNewExpression = extra.parseNewExpression;
  3122. parseNonComputedProperty = extra.parseNonComputedProperty;
  3123. parseObjectProperty = extra.parseObjectProperty;
  3124. parseObjectPropertyKey = extra.parseObjectPropertyKey;
  3125. parsePrimaryExpression = extra.parsePrimaryExpression;
  3126. parsePostfixExpression = extra.parsePostfixExpression;
  3127. parseProgram = extra.parseProgram;
  3128. parsePropertyFunction = extra.parsePropertyFunction;
  3129. parseStatement = extra.parseStatement;
  3130. parseSwitchCase = extra.parseSwitchCase;
  3131. parseUnaryExpression = extra.parseUnaryExpression;
  3132. parseVariableDeclaration = extra.parseVariableDeclaration;
  3133. parseVariableIdentifier = extra.parseVariableIdentifier;
  3134. }
  3135. if (typeof extra.scanRegExp === 'function') {
  3136. advance = extra.advance;
  3137. scanRegExp = extra.scanRegExp;
  3138. }
  3139. }
  3140. // This is used to modify the delegate.
  3141. function extend(object, properties) {
  3142. var entry, result = {};
  3143. for (entry in object) {
  3144. if (object.hasOwnProperty(entry)) {
  3145. result[entry] = object[entry];
  3146. }
  3147. }
  3148. for (entry in properties) {
  3149. if (properties.hasOwnProperty(entry)) {
  3150. result[entry] = properties[entry];
  3151. }
  3152. }
  3153. return result;
  3154. }
  3155. function tokenize(code, options) {
  3156. var toString,
  3157. token,
  3158. tokens;
  3159. toString = String;
  3160. if (typeof code !== 'string' && !(code instanceof String)) {
  3161. code = toString(code);
  3162. }
  3163. delegate = SyntaxTreeDelegate;
  3164. source = code;
  3165. index = 0;
  3166. lineNumber = (source.length > 0) ? 1 : 0;
  3167. lineStart = 0;
  3168. length = source.length;
  3169. lookahead = null;
  3170. state = {
  3171. allowIn: true,
  3172. labelSet: {},
  3173. inFunctionBody: false,
  3174. inIteration: false,
  3175. inSwitch: false
  3176. };
  3177. extra = {};
  3178. // Options matching.
  3179. options = options || {};
  3180. // Of course we collect tokens here.
  3181. options.tokens = true;
  3182. extra.tokens = [];
  3183. extra.tokenize = true;
  3184. // The following two fields are necessary to compute the Regex tokens.
  3185. extra.openParenToken = -1;
  3186. extra.openCurlyToken = -1;
  3187. extra.range = (typeof options.range === 'boolean') && options.range;
  3188. extra.loc = (typeof options.loc === 'boolean') && options.loc;
  3189. if (typeof options.comment === 'boolean' && options.comment) {
  3190. extra.comments = [];
  3191. }
  3192. if (typeof options.tolerant === 'boolean' && options.tolerant) {
  3193. extra.errors = [];
  3194. }
  3195. if (length > 0) {
  3196. if (typeof source[0] === 'undefined') {
  3197. // Try first to convert to a string. This is good as fast path
  3198. // for old IE which understands string indexing for string
  3199. // literals only and not for string object.
  3200. if (code instanceof String) {
  3201. source = code.valueOf();
  3202. }
  3203. }
  3204. }
  3205. patch();
  3206. try {
  3207. peek();
  3208. if (lookahead.type === Token.EOF) {
  3209. return extra.tokens;
  3210. }
  3211. token = lex();
  3212. while (lookahead.type !== Token.EOF) {
  3213. try {
  3214. token = lex();
  3215. } catch (lexError) {
  3216. token = lookahead;
  3217. if (extra.errors) {
  3218. extra.errors.push(lexError);
  3219. // We have to break on the first error
  3220. // to avoid infinite loops.
  3221. break;
  3222. } else {
  3223. throw lexError;
  3224. }
  3225. }
  3226. }
  3227. filterTokenLocation();
  3228. tokens = extra.tokens;
  3229. if (typeof extra.comments !== 'undefined') {
  3230. filterCommentLocation();
  3231. tokens.comments = extra.comments;
  3232. }
  3233. if (typeof extra.errors !== 'undefined') {
  3234. tokens.errors = extra.errors;
  3235. }
  3236. } catch (e) {
  3237. throw e;
  3238. } finally {
  3239. unpatch();
  3240. extra = {};
  3241. }
  3242. return tokens;
  3243. }
  3244. function parse(code, options) {
  3245. var program, toString;
  3246. toString = String;
  3247. if (typeof code !== 'string' && !(code instanceof String)) {
  3248. code = toString(code);
  3249. }
  3250. delegate = SyntaxTreeDelegate;
  3251. source = code;
  3252. index = 0;
  3253. lineNumber = (source.length > 0) ? 1 : 0;
  3254. lineStart = 0;
  3255. length = source.length;
  3256. lookahead = null;
  3257. state = {
  3258. allowIn: true,
  3259. labelSet: {},
  3260. inFunctionBody: false,
  3261. inIteration: false,
  3262. inSwitch: false
  3263. };
  3264. extra = {};
  3265. if (typeof options !== 'undefined') {
  3266. extra.range = (typeof options.range === 'boolean') && options.range;
  3267. extra.loc = (typeof options.loc === 'boolean') && options.loc;
  3268. if (extra.loc && options.source !== null && options.source !== undefined) {
  3269. delegate = extend(delegate, {
  3270. 'postProcess': function (node) {
  3271. node.loc.source = toString(options.source);
  3272. return node;
  3273. }
  3274. });
  3275. }
  3276. if (typeof options.tokens === 'boolean' && options.tokens) {
  3277. extra.tokens = [];
  3278. }
  3279. if (typeof options.comment === 'boolean' && options.comment) {
  3280. extra.comments = [];
  3281. }
  3282. if (typeof options.tolerant === 'boolean' && options.tolerant) {
  3283. extra.errors = [];
  3284. }
  3285. }
  3286. if (length > 0) {
  3287. if (typeof source[0] === 'undefined') {
  3288. // Try first to convert to a string. This is good as fast path
  3289. // for old IE which understands string indexing for string
  3290. // literals only and not for string object.
  3291. if (code instanceof String) {
  3292. source = code.valueOf();
  3293. }
  3294. }
  3295. }
  3296. patch();
  3297. try {
  3298. program = parseProgram();
  3299. if (typeof extra.comments !== 'undefined') {
  3300. filterCommentLocation();
  3301. program.comments = extra.comments;
  3302. }
  3303. if (typeof extra.tokens !== 'undefined') {
  3304. filterTokenLocation();
  3305. program.tokens = extra.tokens;
  3306. }
  3307. if (typeof extra.errors !== 'undefined') {
  3308. program.errors = extra.errors;
  3309. }
  3310. if (extra.range || extra.loc) {
  3311. program.body = filterGroup(program.body);
  3312. }
  3313. } catch (e) {
  3314. throw e;
  3315. } finally {
  3316. unpatch();
  3317. extra = {};
  3318. }
  3319. return program;
  3320. }
  3321. // Sync with package.json and component.json.
  3322. exports.version = '1.1.0-dev';
  3323. exports.tokenize = tokenize;
  3324. exports.parse = parse;
  3325. // Deep copy.
  3326. exports.Syntax = (function () {
  3327. var name, types = {};
  3328. if (typeof Object.create === 'function') {
  3329. types = Object.create(null);
  3330. }
  3331. for (name in Syntax) {
  3332. if (Syntax.hasOwnProperty(name)) {
  3333. types[name] = Syntax[name];
  3334. }
  3335. }
  3336. if (typeof Object.freeze === 'function') {
  3337. Object.freeze(types);
  3338. }
  3339. return types;
  3340. }());
  3341. });