as_parser.cpp 97 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562
  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2022 Andreas Jonsson
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any
  6. damages arising from the use of this software.
  7. Permission is granted to anyone to use this software for any
  8. purpose, including commercial applications, and to alter it and
  9. redistribute it freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you
  11. must not claim that you wrote the original software. If you use
  12. this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and
  15. must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. The original version of this library can be located at:
  19. http://www.angelcode.com/angelscript/
  20. Andreas Jonsson
  21. [email protected]
  22. */
  23. //
  24. // as_parser.cpp
  25. //
  26. // This class parses the script code and builds a tree for compilation
  27. //
  28. //
  29. // I've documented the syntax in Extended BNF. You'll find it by doing a search in
  30. // this file by "BNF:". The starting point for the script language is SCRIPT ::=.
  31. //
  32. // Ref: http://matt.might.net/articles/grammars-bnf-ebnf/
  33. //
  34. // ( ) - used for grouping
  35. // { } - 0 or more repetitions
  36. // [ ] - optional
  37. // | - or
  38. // ' ' - token
  39. //
  40. #include "as_config.h"
  41. #include "as_parser.h"
  42. #include "as_tokendef.h"
  43. #include "as_texts.h"
  44. #include "as_debug.h"
  45. #ifdef _MSC_VER
  46. #pragma warning(disable:4702) // unreachable code
  47. #endif
  48. BEGIN_AS_NAMESPACE
  49. asCParser::asCParser(asCBuilder *builder)
  50. {
  51. this->builder = builder;
  52. this->engine = builder->engine;
  53. script = 0;
  54. scriptNode = 0;
  55. checkValidTypes = false;
  56. isParsingAppInterface = false;
  57. }
  58. asCParser::~asCParser()
  59. {
  60. Reset();
  61. }
  62. void asCParser::Reset()
  63. {
  64. errorWhileParsing = false;
  65. isSyntaxError = false;
  66. checkValidTypes = false;
  67. isParsingAppInterface = false;
  68. sourcePos = 0;
  69. if( scriptNode )
  70. {
  71. scriptNode->Destroy(engine);
  72. }
  73. scriptNode = 0;
  74. script = 0;
  75. lastToken.pos = size_t(-1);
  76. }
  77. asCScriptNode *asCParser::GetScriptNode()
  78. {
  79. return scriptNode;
  80. }
  81. int asCParser::ParseFunctionDefinition(asCScriptCode *in_script, bool in_expectListPattern)
  82. {
  83. Reset();
  84. // Set flag that permits ? as datatype for parameters
  85. isParsingAppInterface = true;
  86. this->script = in_script;
  87. scriptNode = ParseFunctionDefinition();
  88. if( in_expectListPattern )
  89. scriptNode->AddChildLast(ParseListPattern());
  90. // The declaration should end after the definition
  91. if( !isSyntaxError )
  92. {
  93. sToken t;
  94. GetToken(&t);
  95. if( t.type != ttEnd )
  96. {
  97. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)), &t);
  98. Error(InsteadFound(t), &t);
  99. return -1;
  100. }
  101. }
  102. if( errorWhileParsing )
  103. return -1;
  104. return 0;
  105. }
  106. asCScriptNode *asCParser::CreateNode(eScriptNode type)
  107. {
  108. void *ptr = engine->memoryMgr.AllocScriptNode();
  109. if( ptr == 0 )
  110. {
  111. // Out of memory
  112. errorWhileParsing = true;
  113. return 0;
  114. }
  115. return new(ptr) asCScriptNode(type);
  116. }
  117. int asCParser::ParseDataType(asCScriptCode *in_script, bool in_isReturnType)
  118. {
  119. Reset();
  120. this->script = in_script;
  121. scriptNode = CreateNode(snDataType);
  122. if( scriptNode == 0 ) return -1;
  123. scriptNode->AddChildLast(ParseType(true));
  124. if( isSyntaxError ) return -1;
  125. if( in_isReturnType )
  126. {
  127. scriptNode->AddChildLast(ParseTypeMod(false));
  128. if( isSyntaxError ) return -1;
  129. }
  130. // The declaration should end after the type
  131. sToken t;
  132. GetToken(&t);
  133. if( t.type != ttEnd )
  134. {
  135. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)), &t);
  136. Error(InsteadFound(t), &t);
  137. return -1;
  138. }
  139. if( errorWhileParsing )
  140. return -1;
  141. return 0;
  142. }
  143. // Parse a template declaration: IDENTIFIER '<' 'class'? IDENTIFIER '>'
  144. int asCParser::ParseTemplateDecl(asCScriptCode *in_script)
  145. {
  146. Reset();
  147. this->script = in_script;
  148. scriptNode = CreateNode(snUndefined);
  149. if( scriptNode == 0 ) return -1;
  150. scriptNode->AddChildLast(ParseIdentifier());
  151. if( isSyntaxError ) return -1;
  152. sToken t;
  153. GetToken(&t);
  154. if( t.type != ttLessThan )
  155. {
  156. Error(ExpectedToken(asCTokenizer::GetDefinition(ttLessThan)), &t);
  157. Error(InsteadFound(t), &t);
  158. return -1;
  159. }
  160. // The class token is optional
  161. GetToken(&t);
  162. if( t.type != ttClass )
  163. RewindTo(&t);
  164. scriptNode->AddChildLast(ParseIdentifier());
  165. if( isSyntaxError ) return -1;
  166. // There can be multiple sub types
  167. GetToken(&t);
  168. // Parse template types by list separator
  169. while(t.type == ttListSeparator)
  170. {
  171. GetToken(&t);
  172. if( t.type != ttClass )
  173. RewindTo(&t);
  174. scriptNode->AddChildLast(ParseIdentifier());
  175. if( isSyntaxError ) return -1;
  176. GetToken(&t);
  177. }
  178. if( t.type != ttGreaterThan )
  179. {
  180. Error(ExpectedToken(asCTokenizer::GetDefinition(ttGreaterThan)), &t);
  181. Error(InsteadFound(t), &t);
  182. return -1;
  183. }
  184. GetToken(&t);
  185. if( t.type != ttEnd )
  186. {
  187. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)), &t);
  188. Error(InsteadFound(t), &t);
  189. return -1;
  190. }
  191. if( errorWhileParsing )
  192. return -1;
  193. return 0;
  194. }
  195. int asCParser::ParsePropertyDeclaration(asCScriptCode *in_script)
  196. {
  197. Reset();
  198. this->script = in_script;
  199. scriptNode = CreateNode(snDeclaration);
  200. if( scriptNode == 0 ) return -1;
  201. scriptNode->AddChildLast(ParseType(true));
  202. if( isSyntaxError ) return -1;
  203. // Allow optional '&' to indicate that the property is indirect, i.e. stored as reference
  204. sToken t;
  205. GetToken(&t);
  206. RewindTo(&t);
  207. if( t.type == ttAmp )
  208. scriptNode->AddChildLast(ParseToken(ttAmp));
  209. // Allow optional namespace to be defined before the identifier in case
  210. // the declaration is to be used for searching for an existing property
  211. ParseOptionalScope(scriptNode);
  212. scriptNode->AddChildLast(ParseIdentifier());
  213. if( isSyntaxError ) return -1;
  214. // The declaration should end after the identifier
  215. GetToken(&t);
  216. if( t.type != ttEnd )
  217. {
  218. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)), &t);
  219. Error(InsteadFound(t), &t);
  220. return -1;
  221. }
  222. return 0;
  223. }
  224. // BNF:5: SCOPE ::= ['::'] {IDENTIFIER '::'} [IDENTIFIER ['<' TYPE {',' TYPE} '>'] '::']
  225. void asCParser::ParseOptionalScope(asCScriptNode *node)
  226. {
  227. asCScriptNode *scope = CreateNode(snScope);
  228. sToken t1, t2;
  229. GetToken(&t1);
  230. GetToken(&t2);
  231. if( t1.type == ttScope )
  232. {
  233. RewindTo(&t1);
  234. scope->AddChildLast(ParseToken(ttScope));
  235. GetToken(&t1);
  236. GetToken(&t2);
  237. }
  238. while( t1.type == ttIdentifier && t2.type == ttScope )
  239. {
  240. RewindTo(&t1);
  241. scope->AddChildLast(ParseIdentifier());
  242. scope->AddChildLast(ParseToken(ttScope));
  243. GetToken(&t1);
  244. GetToken(&t2);
  245. }
  246. // The innermost scope may be a template type
  247. if( t1.type == ttIdentifier && t2.type == ttLessThan )
  248. {
  249. tempString.Assign(&script->code[t1.pos], t1.length);
  250. if (engine->IsTemplateType(tempString.AddressOf()))
  251. {
  252. RewindTo(&t1);
  253. asCScriptNode *restore = scope->lastChild;
  254. scope->AddChildLast(ParseIdentifier());
  255. if (ParseTemplTypeList(scope, false))
  256. {
  257. GetToken(&t2);
  258. if (t2.type == ttScope)
  259. {
  260. // Template type is part of the scope
  261. // Nothing more needs to be done
  262. node->AddChildLast(scope);
  263. return;
  264. }
  265. else
  266. {
  267. // The template type is not part of the scope
  268. // Rewind to the template type and end the scope
  269. RewindTo(&t1);
  270. // Restore the previously parsed node
  271. while (scope->lastChild != restore)
  272. {
  273. asCScriptNode *last = scope->lastChild;
  274. last->DisconnectParent();
  275. last->Destroy(engine);
  276. }
  277. if( scope->lastChild )
  278. node->AddChildLast(scope);
  279. else
  280. scope->Destroy(engine);
  281. return;
  282. }
  283. }
  284. }
  285. }
  286. // The identifier is not part of the scope
  287. RewindTo(&t1);
  288. if (scope->lastChild)
  289. node->AddChildLast(scope);
  290. else
  291. scope->Destroy(engine);
  292. }
  293. asCScriptNode *asCParser::ParseFunctionDefinition()
  294. {
  295. asCScriptNode *node = CreateNode(snFunction);
  296. if( node == 0 ) return 0;
  297. node->AddChildLast(ParseType(true));
  298. if( isSyntaxError ) return node;
  299. node->AddChildLast(ParseTypeMod(false));
  300. if( isSyntaxError ) return node;
  301. ParseOptionalScope(node);
  302. node->AddChildLast(ParseIdentifier());
  303. if( isSyntaxError ) return node;
  304. node->AddChildLast(ParseParameterList());
  305. if( isSyntaxError ) return node;
  306. // Parse an optional 'const' after the function definition (used for object methods)
  307. sToken t1;
  308. GetToken(&t1);
  309. RewindTo(&t1);
  310. if( t1.type == ttConst )
  311. node->AddChildLast(ParseToken(ttConst));
  312. // Parse optional attributes
  313. ParseMethodAttributes(node);
  314. return node;
  315. }
  316. // BNF:4: TYPEMOD ::= ['&' ['in' | 'out' | 'inout']]
  317. asCScriptNode *asCParser::ParseTypeMod(bool isParam)
  318. {
  319. asCScriptNode *node = CreateNode(snDataType);
  320. if( node == 0 ) return 0;
  321. sToken t;
  322. // Parse possible & token
  323. GetToken(&t);
  324. RewindTo(&t);
  325. if( t.type == ttAmp )
  326. {
  327. node->AddChildLast(ParseToken(ttAmp));
  328. if( isSyntaxError ) return node;
  329. if( isParam )
  330. {
  331. GetToken(&t);
  332. RewindTo(&t);
  333. if( t.type == ttIn || t.type == ttOut || t.type == ttInOut )
  334. {
  335. int tokens[3] = {ttIn, ttOut, ttInOut};
  336. node->AddChildLast(ParseOneOf(tokens, 3));
  337. }
  338. }
  339. }
  340. // Parse possible + token
  341. GetToken(&t);
  342. RewindTo(&t);
  343. if( t.type == ttPlus )
  344. {
  345. node->AddChildLast(ParseToken(ttPlus));
  346. if( isSyntaxError ) return node;
  347. }
  348. // Parse possible if_handle_then_const token
  349. GetToken(&t);
  350. RewindTo(&t);
  351. if (IdentifierIs(t, IF_HANDLE_TOKEN))
  352. {
  353. node->AddChildLast(ParseToken(ttIdentifier));
  354. if (isSyntaxError) return node;
  355. }
  356. return node;
  357. }
  358. // BNF:4: TYPE ::= ['const'] SCOPE DATATYPE ['<' TYPE {',' TYPE} '>'] { ('[' ']') | ('@' ['const']) }
  359. asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, bool allowAuto)
  360. {
  361. asCScriptNode *node = CreateNode(snDataType);
  362. if( node == 0 ) return 0;
  363. sToken t;
  364. if( allowConst )
  365. {
  366. GetToken(&t);
  367. RewindTo(&t);
  368. if( t.type == ttConst )
  369. {
  370. node->AddChildLast(ParseToken(ttConst));
  371. if( isSyntaxError ) return node;
  372. }
  373. }
  374. // Parse scope prefix
  375. ParseOptionalScope(node);
  376. // Parse the actual type
  377. node->AddChildLast(ParseDataType(allowVariableType, allowAuto));
  378. if( isSyntaxError ) return node;
  379. // If the datatype is a template type, then parse the subtype within the < >
  380. GetToken(&t);
  381. RewindTo(&t);
  382. asCScriptNode *type = node->lastChild;
  383. tempString.Assign(&script->code[type->tokenPos], type->tokenLength);
  384. if( engine->IsTemplateType(tempString.AddressOf()) && t.type == ttLessThan )
  385. {
  386. ParseTemplTypeList(node);
  387. if (isSyntaxError) return node;
  388. }
  389. // Parse [] and @
  390. GetToken(&t);
  391. RewindTo(&t);
  392. while( t.type == ttOpenBracket || t.type == ttHandle)
  393. {
  394. if( t.type == ttOpenBracket )
  395. {
  396. node->AddChildLast(ParseToken(ttOpenBracket));
  397. if( isSyntaxError ) return node;
  398. GetToken(&t);
  399. if( t.type != ttCloseBracket )
  400. {
  401. Error(ExpectedToken("]"), &t);
  402. Error(InsteadFound(t), &t);
  403. return node;
  404. }
  405. }
  406. else
  407. {
  408. node->AddChildLast(ParseToken(ttHandle));
  409. if( isSyntaxError ) return node;
  410. GetToken(&t);
  411. RewindTo(&t);
  412. if( t.type == ttConst )
  413. {
  414. node->AddChildLast(ParseToken(ttConst));
  415. if( isSyntaxError ) return node;
  416. }
  417. }
  418. GetToken(&t);
  419. RewindTo(&t);
  420. }
  421. return node;
  422. }
  423. // This parses a template type list, e.g. <type, type, type>
  424. // If 'required' is false, and the template type list is not valid,
  425. // then no change will be done and the function returns false. This
  426. // can be used as do an optional parsing
  427. bool asCParser::ParseTemplTypeList(asCScriptNode *node, bool required)
  428. {
  429. sToken t;
  430. bool isValid = true;
  431. // Remember the last child, so we can restore the state if needed
  432. asCScriptNode *last = node->lastChild;
  433. // Starts with '<'
  434. GetToken(&t);
  435. if (t.type != ttLessThan)
  436. {
  437. if (required)
  438. {
  439. Error(ExpectedToken(asCTokenizer::GetDefinition(ttLessThan)), &t);
  440. Error(InsteadFound(t), &t);
  441. }
  442. return false;
  443. }
  444. // At least one type
  445. // TODO: child funcdef: Make this work with !required
  446. node->AddChildLast(ParseType(true, false));
  447. if (isSyntaxError) return false;
  448. GetToken(&t);
  449. // Parse template types by list separator
  450. while (t.type == ttListSeparator)
  451. {
  452. // TODO: child funcdef: Make this work with !required
  453. node->AddChildLast(ParseType(true, false));
  454. if (isSyntaxError) return false;
  455. GetToken(&t);
  456. }
  457. // End with '>'
  458. // Accept >> and >>> tokens too. But then force the tokenizer to move
  459. // only 1 character ahead (thus splitting the token in two).
  460. if (script->code[t.pos] != '>')
  461. {
  462. if (required)
  463. {
  464. Error(ExpectedToken(asCTokenizer::GetDefinition(ttGreaterThan)), &t);
  465. Error(InsteadFound(t), &t);
  466. }
  467. else
  468. isValid = false;
  469. }
  470. else
  471. {
  472. // Break the token so that only the first > is parsed
  473. SetPos(t.pos + 1);
  474. }
  475. if (!required && !isValid)
  476. {
  477. // Restore the original state before returning
  478. while (node->lastChild != last)
  479. {
  480. asCScriptNode *n = node->lastChild;
  481. n->DisconnectParent();
  482. n->Destroy(engine);
  483. }
  484. return false;
  485. }
  486. // The template type list was parsed OK
  487. return true;
  488. }
  489. asCScriptNode *asCParser::ParseToken(int token)
  490. {
  491. asCScriptNode *node = CreateNode(snUndefined);
  492. if( node == 0 ) return 0;
  493. sToken t1;
  494. GetToken(&t1);
  495. if( t1.type != token )
  496. {
  497. Error(ExpectedToken(asCTokenizer::GetDefinition(token)), &t1);
  498. Error(InsteadFound(t1), &t1);
  499. return node;
  500. }
  501. node->SetToken(&t1);
  502. node->UpdateSourcePos(t1.pos, t1.length);
  503. return node;
  504. }
  505. asCScriptNode *asCParser::ParseOneOf(int *tokens, int count)
  506. {
  507. asCScriptNode *node = CreateNode(snUndefined);
  508. if( node == 0 ) return 0;
  509. sToken t1;
  510. GetToken(&t1);
  511. int n;
  512. for( n = 0; n < count; n++ )
  513. {
  514. if( tokens[n] == t1.type )
  515. break;
  516. }
  517. if( n == count )
  518. {
  519. Error(ExpectedOneOf(tokens, count), &t1);
  520. Error(InsteadFound(t1), &t1);
  521. return node;
  522. }
  523. node->SetToken(&t1);
  524. node->UpdateSourcePos(t1.pos, t1.length);
  525. return node;
  526. }
  527. // BNF:5: DATATYPE ::= (IDENTIFIER | PRIMTYPE | '?' | 'auto')
  528. asCScriptNode *asCParser::ParseDataType(bool allowVariableType, bool allowAuto)
  529. {
  530. asCScriptNode *node = CreateNode(snDataType);
  531. if( node == 0 ) return 0;
  532. sToken t1;
  533. GetToken(&t1);
  534. if( !IsDataType(t1) && !(allowVariableType && t1.type == ttQuestion) && !(allowAuto && t1.type == ttAuto) )
  535. {
  536. if( t1.type == ttIdentifier )
  537. {
  538. asCString errMsg;
  539. tempString.Assign(&script->code[t1.pos], t1.length);
  540. errMsg.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, tempString.AddressOf());
  541. Error(errMsg, &t1);
  542. }
  543. else if( t1.type == ttAuto )
  544. {
  545. Error(TXT_AUTO_NOT_ALLOWED, &t1);
  546. }
  547. else
  548. {
  549. Error(TXT_EXPECTED_DATA_TYPE, &t1);
  550. Error(InsteadFound(t1), &t1);
  551. }
  552. return node;
  553. }
  554. node->SetToken(&t1);
  555. node->UpdateSourcePos(t1.pos, t1.length);
  556. return node;
  557. }
  558. // BNF:6: PRIMTYPE ::= 'void' | 'int' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint' | 'uint8' | 'uint16' | 'uint32' | 'uint64' | 'float' | 'double' | 'bool'
  559. asCScriptNode *asCParser::ParseRealType()
  560. {
  561. asCScriptNode *node = CreateNode(snDataType);
  562. if( node == 0 ) return 0;
  563. sToken t1;
  564. GetToken(&t1);
  565. if( !IsRealType(t1.type) )
  566. {
  567. Error(TXT_EXPECTED_DATA_TYPE, &t1);
  568. Error(InsteadFound(t1), &t1);
  569. return node;
  570. }
  571. node->SetToken(&t1);
  572. node->UpdateSourcePos(t1.pos, t1.length);
  573. return node;
  574. }
  575. // BNF:17: IDENTIFIER ::= single token: starts with letter or _, can include any letter and digit, same as in C++
  576. asCScriptNode *asCParser::ParseIdentifier()
  577. {
  578. asCScriptNode *node = CreateNode(snIdentifier);
  579. if( node == 0 ) return 0;
  580. sToken t1;
  581. GetToken(&t1);
  582. if( t1.type != ttIdentifier )
  583. {
  584. Error(TXT_EXPECTED_IDENTIFIER, &t1);
  585. Error(InsteadFound(t1), &t1);
  586. return node;
  587. }
  588. node->SetToken(&t1);
  589. node->UpdateSourcePos(t1.pos, t1.length);
  590. return node;
  591. }
  592. // BNF:3: PARAMLIST ::= '(' ['void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]})] ')'
  593. asCScriptNode *asCParser::ParseParameterList()
  594. {
  595. asCScriptNode *node = CreateNode(snParameterList);
  596. if( node == 0 ) return 0;
  597. sToken t1;
  598. GetToken(&t1);
  599. if( t1.type != ttOpenParenthesis)
  600. {
  601. Error(ExpectedToken("("), &t1);
  602. Error(InsteadFound(t1), &t1);
  603. return node;
  604. }
  605. node->UpdateSourcePos(t1.pos, t1.length);
  606. GetToken(&t1);
  607. if( t1.type == ttCloseParenthesis )
  608. {
  609. node->UpdateSourcePos(t1.pos, t1.length);
  610. // Statement block is finished
  611. return node;
  612. }
  613. else
  614. {
  615. // If the parameter list is just (void) then the void token should be ignored
  616. if( t1.type == ttVoid )
  617. {
  618. sToken t2;
  619. GetToken(&t2);
  620. if( t2.type == ttCloseParenthesis)
  621. {
  622. node->UpdateSourcePos(t2.pos, t2.length);
  623. return node;
  624. }
  625. }
  626. RewindTo(&t1);
  627. for(;;)
  628. {
  629. // Parse data type
  630. node->AddChildLast(ParseType(true, isParsingAppInterface));
  631. if( isSyntaxError ) return node;
  632. node->AddChildLast(ParseTypeMod(true));
  633. if( isSyntaxError ) return node;
  634. // Parse optional identifier
  635. GetToken(&t1);
  636. if( t1.type == ttIdentifier )
  637. {
  638. RewindTo(&t1);
  639. node->AddChildLast(ParseIdentifier());
  640. if( isSyntaxError ) return node;
  641. GetToken(&t1);
  642. }
  643. // Parse optional expression for the default arg
  644. if( t1.type == ttAssignment )
  645. {
  646. // Do a superficial parsing of the default argument
  647. // The actual parsing will be done when the argument is compiled for a function call
  648. node->AddChildLast(SuperficiallyParseExpression());
  649. if( isSyntaxError ) return node;
  650. GetToken(&t1);
  651. }
  652. // Check if list continues
  653. if( t1.type == ttCloseParenthesis)
  654. {
  655. node->UpdateSourcePos(t1.pos, t1.length);
  656. return node;
  657. }
  658. else if( t1.type == ttListSeparator )
  659. continue;
  660. else
  661. {
  662. Error(ExpectedTokens(")", ","), &t1);
  663. Error(InsteadFound(t1), &t1);
  664. return node;
  665. }
  666. }
  667. }
  668. UNREACHABLE_RETURN;
  669. }
  670. asCScriptNode *asCParser::SuperficiallyParseExpression()
  671. {
  672. asCScriptNode *node = CreateNode(snExpression);
  673. if( node == 0 ) return 0;
  674. // Simply parse everything until the first , or ), whichever comes first.
  675. // Keeping in mind that () and {} can group expressions.
  676. sToken start;
  677. GetToken(&start);
  678. RewindTo(&start);
  679. asCString stack;
  680. sToken t;
  681. for(;;)
  682. {
  683. GetToken(&t);
  684. if( t.type == ttOpenParenthesis)
  685. stack += "(";
  686. else if( t.type == ttCloseParenthesis)
  687. {
  688. if( stack == "" )
  689. {
  690. // Expression has ended. This token is not part of expression
  691. RewindTo(&t);
  692. break;
  693. }
  694. else if( stack[stack.GetLength()-1] == '(' )
  695. {
  696. // Group has ended
  697. stack.SetLength(stack.GetLength()-1);
  698. }
  699. else
  700. {
  701. // Wrong syntax
  702. RewindTo(&t);
  703. asCString str;
  704. str.Format(TXT_UNEXPECTED_TOKEN_s, ")");
  705. Error(str, &t);
  706. return node;
  707. }
  708. }
  709. else if( t.type == ttListSeparator )
  710. {
  711. if( stack == "" )
  712. {
  713. // Expression has ended. This token is not part of expression
  714. RewindTo(&t);
  715. break;
  716. }
  717. }
  718. else if( t.type == ttStartStatementBlock )
  719. stack += "{";
  720. else if( t.type == ttEndStatementBlock )
  721. {
  722. if( stack == "" || stack[stack.GetLength()-1] != '{' )
  723. {
  724. // Wrong syntax
  725. RewindTo(&t);
  726. asCString str;
  727. str.Format(TXT_UNEXPECTED_TOKEN_s, "}");
  728. Error(str, &t);
  729. return node;
  730. }
  731. else
  732. {
  733. // Group has ended
  734. stack.SetLength(stack.GetLength()-1);
  735. }
  736. }
  737. else if( t.type == ttEndStatement )
  738. {
  739. // Wrong syntax (since we're parsing a default arg expression)
  740. RewindTo(&t);
  741. asCString str;
  742. str.Format(TXT_UNEXPECTED_TOKEN_s, ";");
  743. Error(str, &t);
  744. return node;
  745. }
  746. else if( t.type == ttNonTerminatedStringConstant )
  747. {
  748. RewindTo(&t);
  749. Error(TXT_NONTERMINATED_STRING, &t);
  750. return node;
  751. }
  752. else if( t.type == ttEnd )
  753. {
  754. // Wrong syntax
  755. RewindTo(&t);
  756. Error(TXT_UNEXPECTED_END_OF_FILE, &t);
  757. Info(TXT_WHILE_PARSING_EXPRESSION, &start);
  758. return node;
  759. }
  760. // Include the token in the node
  761. node->UpdateSourcePos(t.pos, t.length);
  762. }
  763. return node;
  764. }
  765. // BNF:18: COMMENT ::= single token: starts with // and ends with new line or starts with /* and ends with */
  766. // BNF:18: WHITESPACE ::= single token: spaces, tab, carriage return, line feed, and UTF8 byte-order-mark
  767. void asCParser::GetToken(sToken *token)
  768. {
  769. // Check if the token has already been parsed
  770. if( lastToken.pos == sourcePos )
  771. {
  772. *token = lastToken;
  773. sourcePos += token->length;
  774. if( token->type == ttWhiteSpace ||
  775. token->type == ttOnelineComment ||
  776. token->type == ttMultilineComment )
  777. GetToken(token);
  778. return;
  779. }
  780. // Parse new token
  781. size_t sourceLength = script->codeLength;
  782. do
  783. {
  784. if( sourcePos >= sourceLength )
  785. {
  786. token->type = ttEnd;
  787. token->length = 0;
  788. }
  789. else
  790. token->type = engine->tok.GetToken(&script->code[sourcePos], sourceLength - sourcePos, &token->length);
  791. token->pos = sourcePos;
  792. // Update state
  793. sourcePos += token->length;
  794. }
  795. // Filter out whitespace and comments
  796. while( token->type == ttWhiteSpace ||
  797. token->type == ttOnelineComment ||
  798. token->type == ttMultilineComment );
  799. }
  800. void asCParser::SetPos(size_t pos)
  801. {
  802. lastToken.pos = size_t(-1);
  803. sourcePos = pos;
  804. }
  805. void asCParser::RewindTo(const sToken *token)
  806. {
  807. // TODO: optimize: Perhaps we can optimize this further by having the parser
  808. // set an explicit return point, after which each token will
  809. // be stored. That way not just one token will be reused but
  810. // no token will have to be tokenized more than once.
  811. // Store the token so it doesn't have to be tokenized again
  812. lastToken = *token;
  813. sourcePos = token->pos;
  814. }
  815. void asCParser::Error(const asCString &text, sToken *token)
  816. {
  817. RewindTo(token);
  818. isSyntaxError = true;
  819. errorWhileParsing = true;
  820. int row, col;
  821. script->ConvertPosToRowCol(token->pos, &row, &col);
  822. if( builder )
  823. builder->WriteError(script->name, text, row, col);
  824. }
  825. void asCParser::Warning(const asCString &text, sToken *token)
  826. {
  827. int row, col;
  828. script->ConvertPosToRowCol(token->pos, &row, &col);
  829. if( builder )
  830. builder->WriteWarning(script->name, text, row, col);
  831. }
  832. void asCParser::Info(const asCString &text, sToken *token)
  833. {
  834. RewindTo(token);
  835. isSyntaxError = true;
  836. errorWhileParsing = true;
  837. int row, col;
  838. script->ConvertPosToRowCol(token->pos, &row, &col);
  839. if( builder )
  840. builder->WriteInfo(script->name, text, row, col, false);
  841. }
  842. bool asCParser::IsRealType(int tokenType)
  843. {
  844. if( tokenType == ttVoid ||
  845. tokenType == ttInt ||
  846. tokenType == ttInt8 ||
  847. tokenType == ttInt16 ||
  848. tokenType == ttInt64 ||
  849. tokenType == ttUInt ||
  850. tokenType == ttUInt8 ||
  851. tokenType == ttUInt16 ||
  852. tokenType == ttUInt64 ||
  853. tokenType == ttFloat ||
  854. tokenType == ttBool ||
  855. tokenType == ttDouble )
  856. return true;
  857. return false;
  858. }
  859. bool asCParser::IsDataType(const sToken &token)
  860. {
  861. if( token.type == ttIdentifier )
  862. {
  863. #ifndef AS_NO_COMPILER
  864. if( checkValidTypes )
  865. {
  866. // Check if this is an existing type, regardless of namespace
  867. tempString.Assign(&script->code[token.pos], token.length);
  868. if( !builder->DoesTypeExist(tempString.AddressOf()) )
  869. return false;
  870. }
  871. #endif
  872. return true;
  873. }
  874. if( IsRealType(token.type) )
  875. return true;
  876. return false;
  877. }
  878. asCString asCParser::ExpectedToken(const char *token)
  879. {
  880. asCString str;
  881. str.Format(TXT_EXPECTED_s, token);
  882. return str;
  883. }
  884. asCString asCParser::ExpectedTokens(const char *t1, const char *t2)
  885. {
  886. asCString str;
  887. str.Format(TXT_EXPECTED_s_OR_s, t1, t2);
  888. return str;
  889. }
  890. asCString asCParser::ExpectedOneOf(int *tokens, int count)
  891. {
  892. asCString str;
  893. str = TXT_EXPECTED_ONE_OF;
  894. for( int n = 0; n < count; n++ )
  895. {
  896. str += asCTokenizer::GetDefinition(tokens[n]);
  897. if( n < count-1 )
  898. str += ", ";
  899. }
  900. return str;
  901. }
  902. asCString asCParser::ExpectedOneOf(const char **tokens, int count)
  903. {
  904. asCString str;
  905. str = TXT_EXPECTED_ONE_OF;
  906. for( int n = 0; n < count; n++ )
  907. {
  908. str += tokens[n];
  909. if( n < count-1 )
  910. str += ", ";
  911. }
  912. return str;
  913. }
  914. asCString asCParser::InsteadFound(sToken &t)
  915. {
  916. asCString str;
  917. if( t.type == ttIdentifier )
  918. {
  919. asCString id(&script->code[t.pos], t.length);
  920. str.Format(TXT_INSTEAD_FOUND_IDENTIFIER_s, id.AddressOf());
  921. }
  922. else if( t.type >= ttIf )
  923. str.Format(TXT_INSTEAD_FOUND_KEYWORD_s, asCTokenizer::GetDefinition(t.type));
  924. else
  925. str.Format(TXT_INSTEAD_FOUND_s, asCTokenizer::GetDefinition(t.type));
  926. return str;
  927. }
  928. asCScriptNode *asCParser::ParseListPattern()
  929. {
  930. asCScriptNode *node = CreateNode(snListPattern);
  931. if( node == 0 ) return 0;
  932. sToken t1;
  933. GetToken(&t1);
  934. if( t1.type != ttStartStatementBlock )
  935. {
  936. Error(ExpectedToken("{"), &t1);
  937. Error(InsteadFound(t1), &t1);
  938. return node;
  939. }
  940. node->UpdateSourcePos(t1.pos, t1.length);
  941. sToken start = t1;
  942. bool isBeginning = true;
  943. bool afterType = false;
  944. while( !isSyntaxError )
  945. {
  946. GetToken(&t1);
  947. if( t1.type == ttEndStatementBlock )
  948. {
  949. if( !afterType )
  950. {
  951. Error(TXT_EXPECTED_DATA_TYPE, &t1);
  952. Error(InsteadFound(t1), &t1);
  953. }
  954. break;
  955. }
  956. else if( t1.type == ttStartStatementBlock )
  957. {
  958. if( afterType )
  959. {
  960. Error(ExpectedTokens(",","}"), &t1);
  961. Error(InsteadFound(t1), &t1);
  962. }
  963. RewindTo(&t1);
  964. node->AddChildLast(ParseListPattern());
  965. afterType = true;
  966. }
  967. else if( t1.type == ttIdentifier && (IdentifierIs(t1, "repeat") || IdentifierIs(t1, "repeat_same")) )
  968. {
  969. if( !isBeginning )
  970. {
  971. asCString msg;
  972. asCString token(&script->code[t1.pos], t1.length);
  973. msg.Format(TXT_UNEXPECTED_TOKEN_s, token.AddressOf());
  974. Error(msg.AddressOf(), &t1);
  975. }
  976. RewindTo(&t1);
  977. node->AddChildLast(ParseIdentifier());
  978. }
  979. else if( t1.type == ttEnd )
  980. {
  981. Error(TXT_UNEXPECTED_END_OF_FILE, &t1);
  982. Info(TXT_WHILE_PARSING_STATEMENT_BLOCK, &start);
  983. break;
  984. }
  985. else if( t1.type == ttListSeparator )
  986. {
  987. if( !afterType )
  988. {
  989. Error(TXT_EXPECTED_DATA_TYPE, &t1);
  990. Error(InsteadFound(t1), &t1);
  991. }
  992. afterType = false;
  993. }
  994. else
  995. {
  996. if( afterType )
  997. {
  998. Error(ExpectedTokens(",", "}"), &t1);
  999. Error(InsteadFound(t1), &t1);
  1000. }
  1001. RewindTo(&t1);
  1002. node->AddChildLast(ParseType(true, true));
  1003. afterType = true;
  1004. }
  1005. isBeginning = false;
  1006. }
  1007. node->UpdateSourcePos(t1.pos, t1.length);
  1008. return node;
  1009. }
  1010. bool asCParser::IdentifierIs(const sToken &t, const char *str)
  1011. {
  1012. if( t.type != ttIdentifier )
  1013. return false;
  1014. return script->TokenEquals(t.pos, t.length, str);
  1015. }
  1016. // BNF:6: FUNCATTR ::= {'override' | 'final' | 'explicit' | 'property'}
  1017. void asCParser::ParseMethodAttributes(asCScriptNode *funcNode)
  1018. {
  1019. sToken t1;
  1020. for(;;)
  1021. {
  1022. GetToken(&t1);
  1023. RewindTo(&t1);
  1024. if( IdentifierIs(t1, FINAL_TOKEN) ||
  1025. IdentifierIs(t1, OVERRIDE_TOKEN) ||
  1026. IdentifierIs(t1, EXPLICIT_TOKEN) ||
  1027. IdentifierIs(t1, PROPERTY_TOKEN) )
  1028. funcNode->AddChildLast(ParseIdentifier());
  1029. else
  1030. break;
  1031. }
  1032. }
  1033. #ifndef AS_NO_COMPILER
  1034. // nextToken is only modified if the current position can be interpreted as
  1035. // type, in this case it is set to the next token after the type tokens
  1036. bool asCParser::IsType(sToken &nextToken)
  1037. {
  1038. // Set a rewind point
  1039. sToken t, t1;
  1040. GetToken(&t);
  1041. // A type can start with a const
  1042. t1 = t;
  1043. if (t1.type == ttConst)
  1044. GetToken(&t1);
  1045. sToken t2;
  1046. if (t1.type != ttAuto)
  1047. {
  1048. // The type may be initiated with the scope operator
  1049. if (t1.type == ttScope)
  1050. GetToken(&t1);
  1051. // The type may be preceded with a multilevel scope
  1052. GetToken(&t2);
  1053. while (t1.type == ttIdentifier)
  1054. {
  1055. if (t2.type == ttScope)
  1056. {
  1057. GetToken(&t1);
  1058. GetToken(&t2);
  1059. continue;
  1060. }
  1061. else if (t2.type == ttLessThan)
  1062. {
  1063. // Template types can also be used as scope identifiers
  1064. RewindTo(&t2);
  1065. if (CheckTemplateType(t1))
  1066. {
  1067. sToken t3;
  1068. GetToken(&t3);
  1069. if (t3.type == ttScope)
  1070. {
  1071. GetToken(&t1);
  1072. GetToken(&t2);
  1073. continue;
  1074. }
  1075. }
  1076. }
  1077. break;
  1078. }
  1079. RewindTo(&t2);
  1080. }
  1081. // We don't validate if the identifier is an actual declared type at this moment
  1082. // as it may wrongly identify the statement as a non-declaration if the user typed
  1083. // the name incorrectly. The real type is validated in ParseDeclaration where a
  1084. // proper error message can be given.
  1085. if (!IsRealType(t1.type) && t1.type != ttIdentifier && t1.type != ttAuto)
  1086. {
  1087. RewindTo(&t);
  1088. return false;
  1089. }
  1090. if (!CheckTemplateType(t1))
  1091. {
  1092. RewindTo(&t);
  1093. return false;
  1094. }
  1095. // Object handles can be interleaved with the array brackets
  1096. // Even though declaring variables with & is invalid we'll accept
  1097. // it here to give an appropriate error message later
  1098. GetToken(&t2);
  1099. while (t2.type == ttHandle || t2.type == ttAmp || t2.type == ttOpenBracket)
  1100. {
  1101. if( t2.type == ttHandle )
  1102. {
  1103. // A handle can optionally be read-only
  1104. sToken t3;
  1105. GetToken(&t3);
  1106. if(t3.type != ttConst )
  1107. RewindTo(&t3);
  1108. }
  1109. else if (t2.type == ttOpenBracket)
  1110. {
  1111. GetToken(&t2);
  1112. if (t2.type != ttCloseBracket)
  1113. {
  1114. RewindTo(&t);
  1115. return false;
  1116. }
  1117. }
  1118. GetToken(&t2);
  1119. }
  1120. // Return the next token so the caller can jump directly to it if desired
  1121. nextToken = t2;
  1122. // Rewind to start point
  1123. RewindTo(&t);
  1124. return true;
  1125. }
  1126. // This function will return true if the current token is not a template, or if it is and
  1127. // the following has a valid syntax for a template type. The source position will be left
  1128. // at the first token after the type in case of success
  1129. bool asCParser::CheckTemplateType(const sToken &t)
  1130. {
  1131. // Is this a template type?
  1132. tempString.Assign(&script->code[t.pos], t.length);
  1133. if( engine->IsTemplateType(tempString.AddressOf()) )
  1134. {
  1135. // If the next token is a < then parse the sub-type too
  1136. sToken t1;
  1137. GetToken(&t1);
  1138. if( t1.type != ttLessThan )
  1139. {
  1140. RewindTo(&t1);
  1141. return true;
  1142. }
  1143. for(;;)
  1144. {
  1145. // There might optionally be a 'const'
  1146. GetToken(&t1);
  1147. if( t1.type == ttConst )
  1148. GetToken(&t1);
  1149. // The type may be initiated with the scope operator
  1150. if( t1.type == ttScope )
  1151. GetToken(&t1);
  1152. // There may be multiple levels of scope operators
  1153. sToken t2;
  1154. GetToken(&t2);
  1155. while( t1.type == ttIdentifier && t2.type == ttScope )
  1156. {
  1157. GetToken(&t1);
  1158. GetToken(&t2);
  1159. }
  1160. RewindTo(&t2);
  1161. // Now there must be a data type
  1162. if( !IsDataType(t1) )
  1163. return false;
  1164. if( !CheckTemplateType(t1) )
  1165. return false;
  1166. GetToken(&t1);
  1167. // Is it a handle or array?
  1168. while( t1.type == ttHandle || t1.type == ttOpenBracket )
  1169. {
  1170. if( t1.type == ttOpenBracket )
  1171. {
  1172. GetToken(&t1);
  1173. if( t1.type != ttCloseBracket )
  1174. return false;
  1175. }
  1176. GetToken(&t1);
  1177. }
  1178. // Was this the last template subtype?
  1179. if( t1.type != ttListSeparator )
  1180. break;
  1181. }
  1182. // Accept >> and >>> tokens too. But then force the tokenizer to move
  1183. // only 1 character ahead (thus splitting the token in two).
  1184. if( script->code[t1.pos] != '>' )
  1185. return false;
  1186. else if( t1.length != 1 )
  1187. {
  1188. // We need to break the token, so that only the first character is parsed
  1189. SetPos(t1.pos + 1);
  1190. }
  1191. }
  1192. return true;
  1193. }
  1194. // BNF:12: CAST ::= 'cast' '<' TYPE '>' '(' ASSIGN ')'
  1195. asCScriptNode *asCParser::ParseCast()
  1196. {
  1197. asCScriptNode *node = CreateNode(snCast);
  1198. if( node == 0 ) return 0;
  1199. sToken t1;
  1200. GetToken(&t1);
  1201. if( t1.type != ttCast )
  1202. {
  1203. Error(ExpectedToken("cast"), &t1);
  1204. Error(InsteadFound(t1), &t1);
  1205. return node;
  1206. }
  1207. node->UpdateSourcePos(t1.pos, t1.length);
  1208. GetToken(&t1);
  1209. if( t1.type != ttLessThan )
  1210. {
  1211. Error(ExpectedToken("<"), &t1);
  1212. Error(InsteadFound(t1), &t1);
  1213. return node;
  1214. }
  1215. // Parse the data type
  1216. node->AddChildLast(ParseType(true));
  1217. if( isSyntaxError ) return node;
  1218. GetToken(&t1);
  1219. if( t1.type != ttGreaterThan )
  1220. {
  1221. Error(ExpectedToken(">"), &t1);
  1222. Error(InsteadFound(t1), &t1);
  1223. return node;
  1224. }
  1225. GetToken(&t1);
  1226. if( t1.type != ttOpenParenthesis)
  1227. {
  1228. Error(ExpectedToken("("), &t1);
  1229. Error(InsteadFound(t1), &t1);
  1230. return node;
  1231. }
  1232. node->AddChildLast(ParseAssignment());
  1233. if( isSyntaxError ) return node;
  1234. GetToken(&t1);
  1235. if( t1.type != ttCloseParenthesis)
  1236. {
  1237. Error(ExpectedToken(")"), &t1);
  1238. Error(InsteadFound(t1), &t1);
  1239. return node;
  1240. }
  1241. node->UpdateSourcePos(t1.pos, t1.length);
  1242. return node;
  1243. }
  1244. // BNF:11: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')' | LAMBDA
  1245. asCScriptNode *asCParser::ParseExprValue()
  1246. {
  1247. asCScriptNode *node = CreateNode(snExprValue);
  1248. if( node == 0 ) return 0;
  1249. sToken t1, t2;
  1250. GetToken(&t1);
  1251. GetToken(&t2);
  1252. RewindTo(&t1);
  1253. // 'void' is a special expression that doesn't do anything (normally used for skipping output arguments)
  1254. if( t1.type == ttVoid )
  1255. node->AddChildLast(ParseToken(ttVoid));
  1256. else if( IsRealType(t1.type) )
  1257. node->AddChildLast(ParseConstructCall());
  1258. else if( t1.type == ttIdentifier || t1.type == ttScope )
  1259. {
  1260. // Check if the expression is an anonymous function
  1261. if( IsLambda() )
  1262. {
  1263. node->AddChildLast(ParseLambda());
  1264. }
  1265. else
  1266. {
  1267. // Determine the last identifier in order to check if it is a type
  1268. sToken t;
  1269. if( t1.type == ttScope ) t = t2; else t = t1;
  1270. RewindTo(&t);
  1271. GetToken(&t2);
  1272. while( t.type == ttIdentifier )
  1273. {
  1274. t2 = t;
  1275. GetToken(&t);
  1276. if( t.type == ttScope )
  1277. GetToken(&t);
  1278. else
  1279. break;
  1280. }
  1281. bool isDataType = IsDataType(t2);
  1282. bool isTemplateType = false;
  1283. if( isDataType )
  1284. {
  1285. // Is this a template type?
  1286. tempString.Assign(&script->code[t2.pos], t2.length);
  1287. if( engine->IsTemplateType(tempString.AddressOf()) )
  1288. isTemplateType = true;
  1289. }
  1290. GetToken(&t2);
  1291. // Rewind so the real parsing can be done, after deciding what to parse
  1292. RewindTo(&t1);
  1293. // Check if this is a construct call
  1294. // Just 'type()' isn't considered a construct call, because type may just be a function/method name.
  1295. // The compiler will have to sort this out, since the parser doesn't have enough information.
  1296. if( isDataType && (t.type == ttOpenBracket && t2.type == ttCloseBracket) ) // type[]()
  1297. node->AddChildLast(ParseConstructCall());
  1298. else if( isTemplateType && t.type == ttLessThan ) // type<t>()
  1299. node->AddChildLast(ParseConstructCall());
  1300. else if( IsFunctionCall() )
  1301. node->AddChildLast(ParseFunctionCall());
  1302. else
  1303. node->AddChildLast(ParseVariableAccess());
  1304. }
  1305. }
  1306. else if( t1.type == ttCast )
  1307. node->AddChildLast(ParseCast());
  1308. else if( IsConstant(t1.type) )
  1309. node->AddChildLast(ParseConstant());
  1310. else if( t1.type == ttOpenParenthesis)
  1311. {
  1312. GetToken(&t1);
  1313. node->UpdateSourcePos(t1.pos, t1.length);
  1314. node->AddChildLast(ParseAssignment());
  1315. if( isSyntaxError ) return node;
  1316. GetToken(&t1);
  1317. if( t1.type != ttCloseParenthesis)
  1318. {
  1319. Error(ExpectedToken(")"), &t1);
  1320. Error(InsteadFound(t1), &t1);
  1321. }
  1322. node->UpdateSourcePos(t1.pos, t1.length);
  1323. }
  1324. else
  1325. {
  1326. Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1);
  1327. Error(InsteadFound(t1), &t1);
  1328. }
  1329. return node;
  1330. }
  1331. // BNF:12: LITERAL ::= NUMBER | STRING | BITS | 'true' | 'false' | 'null'
  1332. // BNF:17: NUMBER ::= single token: includes integers and real numbers, same as C++
  1333. // BNF:17: STRING ::= single token: single quoted ', double quoted ", or heredoc multi-line string """
  1334. // BNF:17: BITS ::= single token: binary 0b or 0B, octal 0o or 0O, decimal 0d or 0D, hexadecimal 0x or 0X
  1335. asCScriptNode *asCParser::ParseConstant()
  1336. {
  1337. asCScriptNode *node = CreateNode(snConstant);
  1338. if( node == 0 ) return 0;
  1339. sToken t;
  1340. GetToken(&t);
  1341. if( !IsConstant(t.type) )
  1342. {
  1343. Error(TXT_EXPECTED_CONSTANT, &t);
  1344. Error(InsteadFound(t), &t);
  1345. return node;
  1346. }
  1347. node->SetToken(&t);
  1348. node->UpdateSourcePos(t.pos, t.length);
  1349. // We want to gather a list of string constants to concatenate as children
  1350. if( t.type == ttStringConstant || t.type == ttMultilineStringConstant || t.type == ttHeredocStringConstant )
  1351. RewindTo(&t);
  1352. while( t.type == ttStringConstant || t.type == ttMultilineStringConstant || t.type == ttHeredocStringConstant )
  1353. {
  1354. node->AddChildLast(ParseStringConstant());
  1355. GetToken(&t);
  1356. RewindTo(&t);
  1357. }
  1358. return node;
  1359. }
  1360. bool asCParser::IsLambda()
  1361. {
  1362. bool isLambda = false;
  1363. sToken t;
  1364. GetToken(&t);
  1365. if( t.type == ttIdentifier && IdentifierIs(t, FUNCTION_TOKEN) )
  1366. {
  1367. sToken t2;
  1368. GetToken(&t2);
  1369. if( t2.type == ttOpenParenthesis)
  1370. {
  1371. // Skip until )
  1372. while( t2.type != ttCloseParenthesis && t2.type != ttEnd )
  1373. GetToken(&t2);
  1374. // The next token must be a {
  1375. GetToken(&t2);
  1376. if( t2.type == ttStartStatementBlock )
  1377. isLambda = true;
  1378. }
  1379. }
  1380. RewindTo(&t);
  1381. return isLambda;
  1382. }
  1383. // BNF:12: LAMBDA ::= 'function' '(' [[TYPE TYPEMOD] IDENTIFIER {',' [TYPE TYPEMOD] IDENTIFIER}] ')' STATBLOCK
  1384. asCScriptNode *asCParser::ParseLambda()
  1385. {
  1386. asCScriptNode *node = CreateNode(snFunction);
  1387. if( node == 0 ) return 0;
  1388. sToken t;
  1389. GetToken(&t);
  1390. if( t.type != ttIdentifier || !IdentifierIs(t, FUNCTION_TOKEN) )
  1391. {
  1392. Error(ExpectedToken("function"), &t);
  1393. return node;
  1394. }
  1395. GetToken(&t);
  1396. if( t.type != ttOpenParenthesis)
  1397. {
  1398. Error(ExpectedToken("("), &t);
  1399. return node;
  1400. }
  1401. // Parse optional type before parameter name
  1402. if( IsType(t) && (t.type == ttAmp || t.type == ttIdentifier) )
  1403. {
  1404. node->AddChildLast(ParseType(true));
  1405. if (isSyntaxError) return node;
  1406. node->AddChildLast(ParseTypeMod(true));
  1407. if (isSyntaxError) return node;
  1408. }
  1409. GetToken(&t);
  1410. if( t.type == ttIdentifier )
  1411. {
  1412. RewindTo(&t);
  1413. node->AddChildLast(ParseIdentifier());
  1414. if (isSyntaxError) return node;
  1415. GetToken(&t);
  1416. while( t.type == ttListSeparator )
  1417. {
  1418. // Parse optional type before parameter name
  1419. if (IsType(t) && (t.type == ttAmp || t.type == ttIdentifier))
  1420. {
  1421. node->AddChildLast(ParseType(true));
  1422. if (isSyntaxError) return node;
  1423. node->AddChildLast(ParseTypeMod(true));
  1424. if (isSyntaxError) return node;
  1425. }
  1426. node->AddChildLast(ParseIdentifier());
  1427. if( isSyntaxError ) return node;
  1428. GetToken(&t);
  1429. }
  1430. }
  1431. if( t.type != ttCloseParenthesis)
  1432. {
  1433. Error(ExpectedToken(")"), &t);
  1434. return node;
  1435. }
  1436. // We should just find the end of the statement block here. The statements
  1437. // will be parsed on request by the compiler once it starts the compilation.
  1438. node->AddChildLast(SuperficiallyParseStatementBlock());
  1439. return node;
  1440. }
  1441. asCScriptNode *asCParser::ParseStringConstant()
  1442. {
  1443. asCScriptNode *node = CreateNode(snConstant);
  1444. if( node == 0 ) return 0;
  1445. sToken t;
  1446. GetToken(&t);
  1447. if( t.type != ttStringConstant && t.type != ttMultilineStringConstant && t.type != ttHeredocStringConstant )
  1448. {
  1449. Error(TXT_EXPECTED_STRING, &t);
  1450. Error(InsteadFound(t), &t);
  1451. return node;
  1452. }
  1453. node->SetToken(&t);
  1454. node->UpdateSourcePos(t.pos, t.length);
  1455. return node;
  1456. }
  1457. // BNF:12: FUNCCALL ::= SCOPE IDENTIFIER ARGLIST
  1458. asCScriptNode *asCParser::ParseFunctionCall()
  1459. {
  1460. asCScriptNode *node = CreateNode(snFunctionCall);
  1461. if( node == 0 ) return 0;
  1462. // Parse scope prefix
  1463. ParseOptionalScope(node);
  1464. // Parse the function name followed by the argument list
  1465. node->AddChildLast(ParseIdentifier());
  1466. if( isSyntaxError ) return node;
  1467. node->AddChildLast(ParseArgList());
  1468. return node;
  1469. }
  1470. // BNF:12: VARACCESS ::= SCOPE IDENTIFIER
  1471. asCScriptNode *asCParser::ParseVariableAccess()
  1472. {
  1473. asCScriptNode *node = CreateNode(snVariableAccess);
  1474. if( node == 0 ) return 0;
  1475. // Parse scope prefix
  1476. ParseOptionalScope(node);
  1477. // Parse the variable name
  1478. node->AddChildLast(ParseIdentifier());
  1479. return node;
  1480. }
  1481. // BNF:11: CONSTRUCTCALL ::= TYPE ARGLIST
  1482. asCScriptNode *asCParser::ParseConstructCall()
  1483. {
  1484. asCScriptNode *node = CreateNode(snConstructCall);
  1485. if( node == 0 ) return 0;
  1486. node->AddChildLast(ParseType(false));
  1487. if( isSyntaxError ) return node;
  1488. node->AddChildLast(ParseArgList());
  1489. return node;
  1490. }
  1491. // BNF:13: ARGLIST ::= '(' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':'] ASSIGN} ')'
  1492. asCScriptNode *asCParser::ParseArgList(bool withParenthesis)
  1493. {
  1494. asCScriptNode *node = CreateNode(snArgList);
  1495. if( node == 0 ) return 0;
  1496. sToken t1;
  1497. if( withParenthesis )
  1498. {
  1499. GetToken(&t1);
  1500. if( t1.type != ttOpenParenthesis)
  1501. {
  1502. Error(ExpectedToken("("), &t1);
  1503. Error(InsteadFound(t1), &t1);
  1504. return node;
  1505. }
  1506. node->UpdateSourcePos(t1.pos, t1.length);
  1507. }
  1508. GetToken(&t1);
  1509. if( t1.type == ttCloseParenthesis || t1.type == ttCloseBracket )
  1510. {
  1511. if( withParenthesis )
  1512. {
  1513. if( t1.type == ttCloseParenthesis)
  1514. node->UpdateSourcePos(t1.pos, t1.length);
  1515. else
  1516. {
  1517. asCString str;
  1518. str.Format(TXT_UNEXPECTED_TOKEN_s, asCTokenizer::GetDefinition(ttCloseBracket));
  1519. Error(str.AddressOf(), &t1);
  1520. }
  1521. }
  1522. else
  1523. RewindTo(&t1);
  1524. // Argument list has ended
  1525. return node;
  1526. }
  1527. else
  1528. {
  1529. RewindTo(&t1);
  1530. for(;;)
  1531. {
  1532. // Determine if this is a named argument
  1533. sToken tl, t2;
  1534. GetToken(&tl);
  1535. GetToken(&t2);
  1536. RewindTo(&tl);
  1537. // Named arguments uses the syntax: arg : expr
  1538. // This avoids confusion when the argument has the same name as a local variable, i.e. var = expr
  1539. // It also avoids conflict with expressions to that creates anonymous objects initialized with lists, i.e. type = {...}
  1540. // The alternate syntax: arg = expr, is supported to provide backwards compatibility with 2.29.0
  1541. // TODO: 3.0.0: Remove the alternate syntax
  1542. if( tl.type == ttIdentifier && (t2.type == ttColon || (engine->ep.alterSyntaxNamedArgs && t2.type == ttAssignment)) )
  1543. {
  1544. asCScriptNode *named = CreateNode(snNamedArgument);
  1545. if( named == 0 ) return 0;
  1546. node->AddChildLast(named);
  1547. named->AddChildLast(ParseIdentifier());
  1548. GetToken(&t2);
  1549. if( engine->ep.alterSyntaxNamedArgs == 1 && t2.type == ttAssignment )
  1550. Warning(TXT_NAMED_ARGS_WITH_OLD_SYNTAX, &t2);
  1551. named->AddChildLast(ParseAssignment());
  1552. }
  1553. else
  1554. node->AddChildLast(ParseAssignment());
  1555. if( isSyntaxError ) return node;
  1556. // Check if list continues
  1557. GetToken(&t1);
  1558. if( t1.type == ttListSeparator )
  1559. continue;
  1560. else
  1561. {
  1562. if( withParenthesis )
  1563. {
  1564. if( t1.type == ttCloseParenthesis)
  1565. node->UpdateSourcePos(t1.pos, t1.length);
  1566. else
  1567. {
  1568. Error(ExpectedTokens(")", ","), &t1);
  1569. Error(InsteadFound(t1), &t1);
  1570. }
  1571. }
  1572. else
  1573. RewindTo(&t1);
  1574. return node;
  1575. }
  1576. }
  1577. }
  1578. }
  1579. bool asCParser::IsFunctionCall()
  1580. {
  1581. sToken s;
  1582. sToken t1, t2;
  1583. GetToken(&s);
  1584. t1 = s;
  1585. // A function call may be prefixed with scope resolution
  1586. if( t1.type == ttScope )
  1587. GetToken(&t1);
  1588. GetToken(&t2);
  1589. while( t1.type == ttIdentifier && t2.type == ttScope )
  1590. {
  1591. GetToken(&t1);
  1592. GetToken(&t2);
  1593. }
  1594. // A function call starts with an identifier followed by an argument list
  1595. // The parser doesn't have enough information about scope to determine if the
  1596. // identifier is a datatype, so even if it happens to be the parser will
  1597. // identify the expression as a function call rather than a construct call.
  1598. // The compiler will sort this out later
  1599. if( t1.type != ttIdentifier )
  1600. {
  1601. RewindTo(&s);
  1602. return false;
  1603. }
  1604. if( t2.type == ttOpenParenthesis)
  1605. {
  1606. RewindTo(&s);
  1607. return true;
  1608. }
  1609. RewindTo(&s);
  1610. return false;
  1611. }
  1612. // BNF:13: ASSIGN ::= CONDITION [ ASSIGNOP ASSIGN ]
  1613. asCScriptNode *asCParser::ParseAssignment()
  1614. {
  1615. asCScriptNode *node = CreateNode(snAssignment);
  1616. if( node == 0 ) return 0;
  1617. node->AddChildLast(ParseCondition());
  1618. if( isSyntaxError ) return node;
  1619. sToken t;
  1620. GetToken(&t);
  1621. RewindTo(&t);
  1622. if( IsAssignOperator(t.type) )
  1623. {
  1624. node->AddChildLast(ParseAssignOperator());
  1625. if( isSyntaxError ) return node;
  1626. node->AddChildLast(ParseAssignment());
  1627. if( isSyntaxError ) return node;
  1628. }
  1629. return node;
  1630. }
  1631. // BNF:14: CONDITION ::= EXPR ['?' ASSIGN ':' ASSIGN]
  1632. asCScriptNode *asCParser::ParseCondition()
  1633. {
  1634. asCScriptNode *node = CreateNode(snCondition);
  1635. if( node == 0 ) return 0;
  1636. node->AddChildLast(ParseExpression());
  1637. if( isSyntaxError ) return node;
  1638. sToken t;
  1639. GetToken(&t);
  1640. if( t.type == ttQuestion )
  1641. {
  1642. node->AddChildLast(ParseAssignment());
  1643. if( isSyntaxError ) return node;
  1644. GetToken(&t);
  1645. if( t.type != ttColon )
  1646. {
  1647. Error(ExpectedToken(":"), &t);
  1648. Error(InsteadFound(t), &t);
  1649. return node;
  1650. }
  1651. node->AddChildLast(ParseAssignment());
  1652. if( isSyntaxError ) return node;
  1653. }
  1654. else
  1655. RewindTo(&t);
  1656. return node;
  1657. }
  1658. // BNF:9: EXPR ::= EXPRTERM {EXPROP EXPRTERM}
  1659. asCScriptNode *asCParser::ParseExpression()
  1660. {
  1661. asCScriptNode *node = CreateNode(snExpression);
  1662. if( node == 0 ) return 0;
  1663. node->AddChildLast(ParseExprTerm());
  1664. if( isSyntaxError ) return node;
  1665. for(;;)
  1666. {
  1667. sToken t;
  1668. GetToken(&t);
  1669. RewindTo(&t);
  1670. if( !IsOperator(t.type) )
  1671. return node;
  1672. node->AddChildLast(ParseExprOperator());
  1673. if( isSyntaxError ) return node;
  1674. node->AddChildLast(ParseExprTerm());
  1675. if( isSyntaxError ) return node;
  1676. }
  1677. UNREACHABLE_RETURN;
  1678. }
  1679. // BNF:10: EXPRTERM ::= ([TYPE '='] INITLIST) | ({EXPRPREOP} EXPRVALUE {EXPRPOSTOP})
  1680. asCScriptNode *asCParser::ParseExprTerm()
  1681. {
  1682. asCScriptNode *node = CreateNode(snExprTerm);
  1683. if( node == 0 ) return 0;
  1684. // Check if the expression term is an initialization of a temp object with init list, i.e. type = {...}
  1685. sToken t;
  1686. GetToken(&t);
  1687. sToken t2 = t, t3;
  1688. if (IsDataType(t2) && CheckTemplateType(t2))
  1689. {
  1690. // The next token must be a = followed by a {
  1691. GetToken(&t2);
  1692. GetToken(&t3);
  1693. if (t2.type == ttAssignment && t3.type == ttStartStatementBlock)
  1694. {
  1695. // It is an initialization, now parse it for real
  1696. RewindTo(&t);
  1697. node->AddChildLast(ParseType(false));
  1698. GetToken(&t2);
  1699. node->AddChildLast(ParseInitList());
  1700. return node;
  1701. }
  1702. }
  1703. // Or an anonymous init list, i.e. {...}
  1704. else if( t.type == ttStartStatementBlock )
  1705. {
  1706. RewindTo(&t);
  1707. node->AddChildLast(ParseInitList());
  1708. return node;
  1709. }
  1710. // It wasn't an initialization, so it must be an ordinary expression term
  1711. RewindTo(&t);
  1712. for(;;)
  1713. {
  1714. GetToken(&t);
  1715. RewindTo(&t);
  1716. if( !IsPreOperator(t.type) )
  1717. break;
  1718. node->AddChildLast(ParseExprPreOp());
  1719. if( isSyntaxError ) return node;
  1720. }
  1721. node->AddChildLast(ParseExprValue());
  1722. if( isSyntaxError ) return node;
  1723. for(;;)
  1724. {
  1725. GetToken(&t);
  1726. RewindTo(&t);
  1727. if( !IsPostOperator(t.type) )
  1728. return node;
  1729. node->AddChildLast(ParseExprPostOp());
  1730. if( isSyntaxError ) return node;
  1731. }
  1732. UNREACHABLE_RETURN;
  1733. }
  1734. // BNF:11: EXPRPREOP ::= '-' | '+' | '!' | '++' | '--' | '~' | '@'
  1735. asCScriptNode *asCParser::ParseExprPreOp()
  1736. {
  1737. asCScriptNode *node = CreateNode(snExprPreOp);
  1738. if( node == 0 ) return 0;
  1739. sToken t;
  1740. GetToken(&t);
  1741. if( !IsPreOperator(t.type) )
  1742. {
  1743. Error(TXT_EXPECTED_PRE_OPERATOR, &t);
  1744. Error(InsteadFound(t), &t);
  1745. return node;
  1746. }
  1747. node->SetToken(&t);
  1748. node->UpdateSourcePos(t.pos, t.length);
  1749. return node;
  1750. }
  1751. // BNF:11: EXPRPOSTOP ::= ('.' (FUNCCALL | IDENTIFIER)) | ('[' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':' ASSIGN} ']') | ARGLIST | '++' | '--'
  1752. asCScriptNode *asCParser::ParseExprPostOp()
  1753. {
  1754. asCScriptNode *node = CreateNode(snExprPostOp);
  1755. if( node == 0 ) return 0;
  1756. sToken t;
  1757. GetToken(&t);
  1758. if( !IsPostOperator(t.type) )
  1759. {
  1760. Error(TXT_EXPECTED_POST_OPERATOR, &t);
  1761. Error(InsteadFound(t), &t);
  1762. return node;
  1763. }
  1764. node->SetToken(&t);
  1765. node->UpdateSourcePos(t.pos, t.length);
  1766. if( t.type == ttDot )
  1767. {
  1768. sToken t1, t2;
  1769. GetToken(&t1);
  1770. GetToken(&t2);
  1771. RewindTo(&t1);
  1772. if( t2.type == ttOpenParenthesis)
  1773. node->AddChildLast(ParseFunctionCall());
  1774. else
  1775. node->AddChildLast(ParseIdentifier());
  1776. }
  1777. else if( t.type == ttOpenBracket )
  1778. {
  1779. node->AddChildLast(ParseArgList(false));
  1780. GetToken(&t);
  1781. if( t.type != ttCloseBracket )
  1782. {
  1783. Error(ExpectedToken("]"), &t);
  1784. Error(InsteadFound(t), &t);
  1785. return node;
  1786. }
  1787. node->UpdateSourcePos(t.pos, t.length);
  1788. }
  1789. else if( t.type == ttOpenParenthesis)
  1790. {
  1791. RewindTo(&t);
  1792. node->AddChildLast(ParseArgList());
  1793. }
  1794. return node;
  1795. }
  1796. // BNF:15: EXPROP ::= MATHOP | COMPOP | LOGICOP | BITOP
  1797. // BNF:16: MATHOP ::= '+' | '-' | '*' | '/' | '\%' | '**'
  1798. // BNF:16: COMPOP ::= '==' | '!=' | '<' | '<=' | '>' | '>=' | 'is' | '!is'
  1799. // BNF:16: LOGICOP ::= '&&' | '||' | '^^' | 'and' | 'or' | 'xor'
  1800. // BNF:16: BITOP ::= '&' | '|' | '^' | '<<' | '>>' | '>>>'
  1801. asCScriptNode *asCParser::ParseExprOperator()
  1802. {
  1803. asCScriptNode *node = CreateNode(snExprOperator);
  1804. if( node == 0 ) return 0;
  1805. sToken t;
  1806. GetToken(&t);
  1807. if( !IsOperator(t.type) )
  1808. {
  1809. Error(TXT_EXPECTED_OPERATOR, &t);
  1810. Error(InsteadFound(t), &t);
  1811. return node;
  1812. }
  1813. node->SetToken(&t);
  1814. node->UpdateSourcePos(t.pos, t.length);
  1815. return node;
  1816. }
  1817. // BNF:16: ASSIGNOP ::= '=' | '+=' | '-=' | '*=' | '/=' | '|=' | '&=' | '^=' | '%=' | '**=' | '<<=' | '>>=' | '>>>='
  1818. asCScriptNode *asCParser::ParseAssignOperator()
  1819. {
  1820. asCScriptNode *node = CreateNode(snExprOperator);
  1821. if( node == 0 ) return 0;
  1822. sToken t;
  1823. GetToken(&t);
  1824. if( !IsAssignOperator(t.type) )
  1825. {
  1826. Error(TXT_EXPECTED_OPERATOR, &t);
  1827. Error(InsteadFound(t), &t);
  1828. return node;
  1829. }
  1830. node->SetToken(&t);
  1831. node->UpdateSourcePos(t.pos, t.length);
  1832. return node;
  1833. }
  1834. bool asCParser::IsOperator(int tokenType)
  1835. {
  1836. if( tokenType == ttPlus ||
  1837. tokenType == ttMinus ||
  1838. tokenType == ttStar ||
  1839. tokenType == ttSlash ||
  1840. tokenType == ttPercent ||
  1841. tokenType == ttStarStar ||
  1842. tokenType == ttAnd ||
  1843. tokenType == ttOr ||
  1844. tokenType == ttXor ||
  1845. tokenType == ttEqual ||
  1846. tokenType == ttNotEqual ||
  1847. tokenType == ttLessThan ||
  1848. tokenType == ttLessThanOrEqual ||
  1849. tokenType == ttGreaterThan ||
  1850. tokenType == ttGreaterThanOrEqual ||
  1851. tokenType == ttAmp ||
  1852. tokenType == ttBitOr ||
  1853. tokenType == ttBitXor ||
  1854. tokenType == ttBitShiftLeft ||
  1855. tokenType == ttBitShiftRight ||
  1856. tokenType == ttBitShiftRightArith ||
  1857. tokenType == ttIs ||
  1858. tokenType == ttNotIs )
  1859. return true;
  1860. return false;
  1861. }
  1862. bool asCParser::IsAssignOperator(int tokenType)
  1863. {
  1864. if( tokenType == ttAssignment ||
  1865. tokenType == ttAddAssign ||
  1866. tokenType == ttSubAssign ||
  1867. tokenType == ttMulAssign ||
  1868. tokenType == ttDivAssign ||
  1869. tokenType == ttModAssign ||
  1870. tokenType == ttPowAssign ||
  1871. tokenType == ttAndAssign ||
  1872. tokenType == ttOrAssign ||
  1873. tokenType == ttXorAssign ||
  1874. tokenType == ttShiftLeftAssign ||
  1875. tokenType == ttShiftRightLAssign ||
  1876. tokenType == ttShiftRightAAssign )
  1877. return true;
  1878. return false;
  1879. }
  1880. bool asCParser::IsPreOperator(int tokenType)
  1881. {
  1882. if( tokenType == ttMinus ||
  1883. tokenType == ttPlus ||
  1884. tokenType == ttNot ||
  1885. tokenType == ttInc ||
  1886. tokenType == ttDec ||
  1887. tokenType == ttBitNot ||
  1888. tokenType == ttHandle )
  1889. return true;
  1890. return false;
  1891. }
  1892. bool asCParser::IsPostOperator(int tokenType)
  1893. {
  1894. if( tokenType == ttInc || // post increment
  1895. tokenType == ttDec || // post decrement
  1896. tokenType == ttDot || // member access
  1897. tokenType == ttOpenBracket || // index operator
  1898. tokenType == ttOpenParenthesis) // argument list for call on function pointer
  1899. return true;
  1900. return false;
  1901. }
  1902. bool asCParser::IsConstant(int tokenType)
  1903. {
  1904. if( tokenType == ttIntConstant ||
  1905. tokenType == ttFloatConstant ||
  1906. tokenType == ttDoubleConstant ||
  1907. tokenType == ttStringConstant ||
  1908. tokenType == ttMultilineStringConstant ||
  1909. tokenType == ttHeredocStringConstant ||
  1910. tokenType == ttTrue ||
  1911. tokenType == ttFalse ||
  1912. tokenType == ttBitsConstant ||
  1913. tokenType == ttNull )
  1914. return true;
  1915. return false;
  1916. }
  1917. int asCParser::ParseScript(asCScriptCode *in_script)
  1918. {
  1919. Reset();
  1920. this->script = in_script;
  1921. scriptNode = ParseScript(false);
  1922. if( errorWhileParsing )
  1923. return -1;
  1924. // TODO: Should allow application to request this warning to be generated.
  1925. // It should be off by default, since pre-processor may remove all
  1926. // code from a section while still being meant as valid code
  1927. /*
  1928. // Warn in case there isn't anything in the script
  1929. if( scriptNode->firstChild == 0 )
  1930. {
  1931. if( builder )
  1932. builder->WriteWarning(script->name, TXT_SECTION_IS_EMPTY, 1, 1);
  1933. }
  1934. */
  1935. return 0;
  1936. }
  1937. int asCParser::ParseExpression(asCScriptCode *in_script)
  1938. {
  1939. Reset();
  1940. this->script = in_script;
  1941. checkValidTypes = true;
  1942. scriptNode = ParseExpression();
  1943. if( errorWhileParsing )
  1944. return -1;
  1945. return 0;
  1946. }
  1947. // BNF:1: IMPORT ::= 'import' TYPE ['&'] IDENTIFIER PARAMLIST FUNCATTR 'from' STRING ';'
  1948. asCScriptNode *asCParser::ParseImport()
  1949. {
  1950. asCScriptNode *node = CreateNode(snImport);
  1951. if( node == 0 ) return 0;
  1952. sToken t;
  1953. GetToken(&t);
  1954. if( t.type != ttImport )
  1955. {
  1956. Error(ExpectedToken(asCTokenizer::GetDefinition(ttImport)), &t);
  1957. Error(InsteadFound(t), &t);
  1958. return node;
  1959. }
  1960. node->SetToken(&t);
  1961. node->UpdateSourcePos(t.pos, t.length);
  1962. node->AddChildLast(ParseFunctionDefinition());
  1963. if( isSyntaxError ) return node;
  1964. GetToken(&t);
  1965. if( t.type != ttIdentifier )
  1966. {
  1967. Error(ExpectedToken(FROM_TOKEN), &t);
  1968. Error(InsteadFound(t), &t);
  1969. return node;
  1970. }
  1971. tempString.Assign(&script->code[t.pos], t.length);
  1972. if( tempString != FROM_TOKEN )
  1973. {
  1974. Error(ExpectedToken(FROM_TOKEN), &t);
  1975. Error(InsteadFound(t), &t);
  1976. return node;
  1977. }
  1978. node->UpdateSourcePos(t.pos, t.length);
  1979. GetToken(&t);
  1980. if( t.type != ttStringConstant )
  1981. {
  1982. Error(TXT_EXPECTED_STRING, &t);
  1983. Error(InsteadFound(t), &t);
  1984. return node;
  1985. }
  1986. asCScriptNode *mod = CreateNode(snConstant);
  1987. if( mod == 0 ) return 0;
  1988. node->AddChildLast(mod);
  1989. mod->SetToken(&t);
  1990. mod->UpdateSourcePos(t.pos, t.length);
  1991. GetToken(&t);
  1992. if( t.type != ttEndStatement )
  1993. {
  1994. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEndStatement)), &t);
  1995. Error(InsteadFound(t), &t);
  1996. return node;
  1997. }
  1998. node->UpdateSourcePos(t.pos, t.length);
  1999. return node;
  2000. }
  2001. // BNF:0: SCRIPT ::= {IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VIRTPROP | VAR | FUNC | NAMESPACE | ';'}
  2002. asCScriptNode *asCParser::ParseScript(bool inBlock)
  2003. {
  2004. asCScriptNode *node = CreateNode(snScript);
  2005. if( node == 0 ) return 0;
  2006. // Determine type of node
  2007. for(;;)
  2008. {
  2009. while( !isSyntaxError )
  2010. {
  2011. sToken tStart;
  2012. GetToken(&tStart);
  2013. // Optimize by skipping tokens 'shared', 'external', 'final', 'abstract' so they don't have to be checked in every condition
  2014. sToken t1 = tStart;
  2015. while (IdentifierIs(t1, SHARED_TOKEN) ||
  2016. IdentifierIs(t1, EXTERNAL_TOKEN) ||
  2017. IdentifierIs(t1, FINAL_TOKEN) ||
  2018. IdentifierIs(t1, ABSTRACT_TOKEN))
  2019. GetToken(&t1);
  2020. RewindTo(&tStart);
  2021. if( t1.type == ttImport )
  2022. node->AddChildLast(ParseImport());
  2023. else if( t1.type == ttEnum )
  2024. node->AddChildLast(ParseEnumeration()); // Handle enumerations
  2025. else if( t1.type == ttTypedef )
  2026. node->AddChildLast(ParseTypedef()); // Handle primitive typedefs
  2027. else if( t1.type == ttClass )
  2028. node->AddChildLast(ParseClass());
  2029. else if( t1.type == ttMixin )
  2030. node->AddChildLast(ParseMixin());
  2031. else if( t1.type == ttInterface )
  2032. node->AddChildLast(ParseInterface());
  2033. else if( t1.type == ttFuncDef )
  2034. node->AddChildLast(ParseFuncDef());
  2035. else if( t1.type == ttConst || t1.type == ttScope || t1.type == ttAuto || IsDataType(t1) )
  2036. {
  2037. if( IsVirtualPropertyDecl() )
  2038. node->AddChildLast(ParseVirtualPropertyDecl(false, false));
  2039. else if( IsVarDecl() )
  2040. node->AddChildLast(ParseDeclaration(false, true));
  2041. else
  2042. node->AddChildLast(ParseFunction());
  2043. }
  2044. else if( t1.type == ttEndStatement )
  2045. {
  2046. // Ignore a semicolon by itself
  2047. GetToken(&t1);
  2048. }
  2049. else if( t1.type == ttNamespace )
  2050. node->AddChildLast(ParseNamespace());
  2051. else if( t1.type == ttEnd )
  2052. return node;
  2053. else if( inBlock && t1.type == ttEndStatementBlock )
  2054. return node;
  2055. else
  2056. {
  2057. asCString str;
  2058. const char *t = asCTokenizer::GetDefinition(t1.type);
  2059. if( t == 0 ) t = "<unknown token>";
  2060. str.Format(TXT_UNEXPECTED_TOKEN_s, t);
  2061. Error(str, &t1);
  2062. }
  2063. }
  2064. if( isSyntaxError )
  2065. {
  2066. // Search for either ';' or '{' or end
  2067. sToken t1;
  2068. GetToken(&t1);
  2069. while( t1.type != ttEndStatement && t1.type != ttEnd &&
  2070. t1.type != ttStartStatementBlock )
  2071. GetToken(&t1);
  2072. if( t1.type == ttStartStatementBlock )
  2073. {
  2074. // Find the end of the block and skip nested blocks
  2075. int level = 1;
  2076. while( level > 0 )
  2077. {
  2078. GetToken(&t1);
  2079. if( t1.type == ttStartStatementBlock ) level++;
  2080. if( t1.type == ttEndStatementBlock ) level--;
  2081. if( t1.type == ttEnd ) break;
  2082. }
  2083. }
  2084. isSyntaxError = false;
  2085. }
  2086. }
  2087. UNREACHABLE_RETURN;
  2088. }
  2089. // BNF:1: NAMESPACE ::= 'namespace' IDENTIFIER {'::' IDENTIFIER} '{' SCRIPT '}'
  2090. asCScriptNode *asCParser::ParseNamespace()
  2091. {
  2092. asCScriptNode *node = CreateNode(snNamespace);
  2093. if( node == 0 ) return 0;
  2094. sToken t1;
  2095. GetToken(&t1);
  2096. if( t1.type == ttNamespace )
  2097. node->UpdateSourcePos(t1.pos, t1.length);
  2098. else
  2099. {
  2100. Error(ExpectedToken(asCTokenizer::GetDefinition(ttNamespace)), &t1);
  2101. Error(InsteadFound(t1), &t1);
  2102. }
  2103. node->AddChildLast(ParseIdentifier());
  2104. if( isSyntaxError ) return node;
  2105. asCScriptNode *lowestNode = node;
  2106. GetToken(&t1);
  2107. while (t1.type == ttScope)
  2108. {
  2109. lowestNode->UpdateSourcePos(t1.pos, t1.length);
  2110. asCScriptNode *scopeNode = CreateNode(snScript);
  2111. if (scopeNode == 0)
  2112. return 0;
  2113. lowestNode->AddChildLast(scopeNode);
  2114. lowestNode = CreateNode(snNamespace);
  2115. if (lowestNode == 0)
  2116. return 0;
  2117. scopeNode->AddChildLast(lowestNode);
  2118. lowestNode->AddChildLast(ParseIdentifier());
  2119. if (isSyntaxError)
  2120. return node;
  2121. GetToken(&t1);
  2122. }
  2123. if( t1.type == ttStartStatementBlock )
  2124. node->UpdateSourcePos(t1.pos, t1.length);
  2125. else
  2126. {
  2127. Error(ExpectedToken(asCTokenizer::GetDefinition(ttStartStatementBlock)), &t1);
  2128. Error(InsteadFound(t1), &t1);
  2129. return node;
  2130. }
  2131. sToken start = t1;
  2132. lowestNode->AddChildLast(ParseScript(true));
  2133. if( !isSyntaxError )
  2134. {
  2135. GetToken(&t1);
  2136. if( t1.type == ttEndStatementBlock )
  2137. node->UpdateSourcePos(t1.pos, t1.length);
  2138. else
  2139. {
  2140. if( t1.type == ttEnd )
  2141. Error(TXT_UNEXPECTED_END_OF_FILE, &t1);
  2142. else
  2143. {
  2144. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEndStatementBlock)), &t1);
  2145. Error(InsteadFound(t1), &t1);
  2146. }
  2147. Info(TXT_WHILE_PARSING_NAMESPACE, &start);
  2148. return node;
  2149. }
  2150. }
  2151. return node;
  2152. }
  2153. int asCParser::ParseStatementBlock(asCScriptCode *in_script, asCScriptNode *in_block)
  2154. {
  2155. TimeIt("asCParser::ParseStatementBlock");
  2156. Reset();
  2157. // Tell the parser to validate the identifiers as valid types
  2158. checkValidTypes = true;
  2159. this->script = in_script;
  2160. sourcePos = in_block->tokenPos;
  2161. scriptNode = ParseStatementBlock();
  2162. if( isSyntaxError || errorWhileParsing )
  2163. return -1;
  2164. return 0;
  2165. }
  2166. // BNF:1: ENUM ::= {'shared' | 'external'} 'enum' IDENTIFIER (';' | ('{' IDENTIFIER ['=' EXPR] {',' IDENTIFIER ['=' EXPR]} '}'))
  2167. asCScriptNode *asCParser::ParseEnumeration()
  2168. {
  2169. asCScriptNode *ident;
  2170. asCScriptNode *dataType;
  2171. asCScriptNode *node = CreateNode(snEnum);
  2172. if( node == 0 ) return 0;
  2173. sToken token;
  2174. // Optional 'shared' and 'external' token
  2175. GetToken(&token);
  2176. while( IdentifierIs(token, SHARED_TOKEN) ||
  2177. IdentifierIs(token, EXTERNAL_TOKEN) )
  2178. {
  2179. RewindTo(&token);
  2180. node->AddChildLast(ParseIdentifier());
  2181. if( isSyntaxError ) return node;
  2182. GetToken(&token);
  2183. }
  2184. // Check for enum
  2185. if( token.type != ttEnum )
  2186. {
  2187. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnum)), &token);
  2188. Error(InsteadFound(token), &token);
  2189. return node;
  2190. }
  2191. node->SetToken(&token);
  2192. node->UpdateSourcePos(token.pos, token.length);
  2193. // Get the identifier
  2194. GetToken(&token);
  2195. if(ttIdentifier != token.type)
  2196. {
  2197. Error(TXT_EXPECTED_IDENTIFIER, &token);
  2198. Error(InsteadFound(token), &token);
  2199. return node;
  2200. }
  2201. dataType = CreateNode(snDataType);
  2202. if( dataType == 0 ) return node;
  2203. node->AddChildLast(dataType);
  2204. ident = CreateNode(snIdentifier);
  2205. if( ident == 0 ) return node;
  2206. ident->SetToken(&token);
  2207. ident->UpdateSourcePos(token.pos, token.length);
  2208. dataType->AddChildLast(ident);
  2209. // External shared declarations are ended with ';'
  2210. GetToken(&token);
  2211. if (token.type == ttEndStatement)
  2212. {
  2213. RewindTo(&token);
  2214. node->AddChildLast(ParseToken(ttEndStatement));
  2215. return node;
  2216. }
  2217. // check for the start of the declaration block
  2218. if( token.type != ttStartStatementBlock )
  2219. {
  2220. RewindTo(&token);
  2221. int tokens[] = { ttStartStatementBlock, ttEndStatement };
  2222. Error(ExpectedOneOf(tokens, 2), &token);
  2223. Error(InsteadFound(token), &token);
  2224. return node;
  2225. }
  2226. while(ttEnd != token.type)
  2227. {
  2228. GetToken(&token);
  2229. if( ttEndStatementBlock == token.type )
  2230. {
  2231. RewindTo(&token);
  2232. break;
  2233. }
  2234. if(ttIdentifier != token.type)
  2235. {
  2236. Error(TXT_EXPECTED_IDENTIFIER, &token);
  2237. Error(InsteadFound(token), &token);
  2238. return node;
  2239. }
  2240. // Add the enum element
  2241. ident = CreateNode(snIdentifier);
  2242. if( ident == 0 ) return node;
  2243. ident->SetToken(&token);
  2244. ident->UpdateSourcePos(token.pos, token.length);
  2245. node->AddChildLast(ident);
  2246. GetToken(&token);
  2247. if( token.type == ttAssignment )
  2248. {
  2249. asCScriptNode *tmp;
  2250. RewindTo(&token);
  2251. tmp = SuperficiallyParseVarInit();
  2252. node->AddChildLast(tmp);
  2253. if( isSyntaxError ) return node;
  2254. GetToken(&token);
  2255. }
  2256. if(ttListSeparator != token.type)
  2257. {
  2258. RewindTo(&token);
  2259. break;
  2260. }
  2261. }
  2262. // check for the end of the declaration block
  2263. GetToken(&token);
  2264. if( token.type != ttEndStatementBlock )
  2265. {
  2266. RewindTo(&token);
  2267. Error(ExpectedToken("}"), &token);
  2268. Error(InsteadFound(token), &token);
  2269. return node;
  2270. }
  2271. return node;
  2272. }
  2273. bool asCParser::IsVarDecl()
  2274. {
  2275. // Set start point so that we can rewind
  2276. sToken t;
  2277. GetToken(&t);
  2278. RewindTo(&t);
  2279. // A class property decl can be preceded by 'private' or 'protected'
  2280. sToken t1;
  2281. GetToken(&t1);
  2282. if( t1.type != ttPrivate && t1.type != ttProtected )
  2283. RewindTo(&t1);
  2284. // A variable decl starts with the type
  2285. if (!IsType(t1))
  2286. {
  2287. RewindTo(&t);
  2288. return false;
  2289. }
  2290. // Jump to the token after the type
  2291. RewindTo(&t1);
  2292. GetToken(&t1);
  2293. // The declaration needs to have a name
  2294. if( t1.type != ttIdentifier )
  2295. {
  2296. RewindTo(&t);
  2297. return false;
  2298. }
  2299. // It can be followed by an initialization
  2300. GetToken(&t1);
  2301. if( t1.type == ttEndStatement || t1.type == ttAssignment || t1.type == ttListSeparator )
  2302. {
  2303. RewindTo(&t);
  2304. return true;
  2305. }
  2306. if( t1.type == ttOpenParenthesis)
  2307. {
  2308. // If the closing parenthesis is followed by a statement block,
  2309. // function decorator, or end-of-file, then treat it as a function.
  2310. // A function decl may have nested parenthesis so we need to check
  2311. // for this too.
  2312. int nest = 0;
  2313. while( t1.type != ttEnd )
  2314. {
  2315. if( t1.type == ttOpenParenthesis)
  2316. nest++;
  2317. else if( t1.type == ttCloseParenthesis)
  2318. {
  2319. nest--;
  2320. if( nest == 0 )
  2321. break;
  2322. }
  2323. GetToken(&t1);
  2324. }
  2325. if (t1.type == ttEnd)
  2326. {
  2327. RewindTo(&t);
  2328. return false;
  2329. }
  2330. else
  2331. {
  2332. GetToken(&t1);
  2333. RewindTo(&t);
  2334. if( t1.type == ttStartStatementBlock ||
  2335. t1.type == ttIdentifier || // function decorator
  2336. t1.type == ttEnd )
  2337. return false;
  2338. }
  2339. RewindTo(&t);
  2340. return true;
  2341. }
  2342. RewindTo(&t);
  2343. return false;
  2344. }
  2345. bool asCParser::IsVirtualPropertyDecl()
  2346. {
  2347. // Set start point so that we can rewind
  2348. sToken t;
  2349. GetToken(&t);
  2350. RewindTo(&t);
  2351. // A class property decl can be preceded by 'private' or 'protected'
  2352. sToken t1;
  2353. GetToken(&t1);
  2354. if( t1.type != ttPrivate && t1.type != ttProtected )
  2355. RewindTo(&t1);
  2356. // A variable decl starts with the type
  2357. if (!IsType(t1))
  2358. {
  2359. RewindTo(&t);
  2360. return false;
  2361. }
  2362. // Move to the token after the type
  2363. RewindTo(&t1);
  2364. GetToken(&t1);
  2365. // The decl must have an identifier
  2366. if( t1.type != ttIdentifier )
  2367. {
  2368. RewindTo(&t);
  2369. return false;
  2370. }
  2371. // To be a virtual property it must also have a block for the get/set functions
  2372. GetToken(&t1);
  2373. if( t1.type == ttStartStatementBlock )
  2374. {
  2375. RewindTo(&t);
  2376. return true;
  2377. }
  2378. RewindTo(&t);
  2379. return false;
  2380. }
  2381. bool asCParser::IsFuncDecl(bool isMethod)
  2382. {
  2383. // Set start point so that we can rewind
  2384. sToken t;
  2385. GetToken(&t);
  2386. RewindTo(&t);
  2387. if( isMethod )
  2388. {
  2389. // A class method decl can be preceded by 'private' or 'protected'
  2390. sToken t1, t2;
  2391. GetToken(&t1);
  2392. if( t1.type != ttPrivate && t1.type != ttProtected )
  2393. RewindTo(&t1);
  2394. // A class constructor starts with identifier followed by parenthesis
  2395. // A class destructor starts with the ~ token
  2396. GetToken(&t1);
  2397. GetToken(&t2);
  2398. RewindTo(&t1);
  2399. if( (t1.type == ttIdentifier && t2.type == ttOpenParenthesis) || t1.type == ttBitNot )
  2400. {
  2401. RewindTo(&t);
  2402. return true;
  2403. }
  2404. }
  2405. // A function decl starts with a type
  2406. sToken t1;
  2407. if (!IsType(t1))
  2408. {
  2409. RewindTo(&t);
  2410. return false;
  2411. }
  2412. // Move to the token after the type
  2413. RewindTo(&t1);
  2414. GetToken(&t1);
  2415. // There can be an ampersand if the function returns a reference
  2416. if( t1.type == ttAmp )
  2417. {
  2418. RewindTo(&t);
  2419. return true;
  2420. }
  2421. if( t1.type != ttIdentifier )
  2422. {
  2423. RewindTo(&t);
  2424. return false;
  2425. }
  2426. GetToken(&t1);
  2427. if( t1.type == ttOpenParenthesis)
  2428. {
  2429. // If the closing parenthesis is not followed by a
  2430. // statement block then it is not a function.
  2431. // It's possible that there are nested parenthesis due to default
  2432. // arguments so this should be checked for.
  2433. int nest = 0;
  2434. GetToken(&t1);
  2435. while( (nest || t1.type != ttCloseParenthesis) && t1.type != ttEnd )
  2436. {
  2437. if( t1.type == ttOpenParenthesis)
  2438. nest++;
  2439. if( t1.type == ttCloseParenthesis)
  2440. nest--;
  2441. GetToken(&t1);
  2442. }
  2443. if( t1.type == ttEnd )
  2444. return false;
  2445. else
  2446. {
  2447. if( isMethod )
  2448. {
  2449. // A class method can have a 'const' token after the parameter list
  2450. GetToken(&t1);
  2451. if( t1.type != ttConst )
  2452. RewindTo(&t1);
  2453. }
  2454. // A function may also have any number of additional attributes
  2455. for( ; ; )
  2456. {
  2457. GetToken(&t1);
  2458. if( !IdentifierIs(t1, FINAL_TOKEN) &&
  2459. !IdentifierIs(t1, OVERRIDE_TOKEN) &&
  2460. !IdentifierIs(t1, EXPLICIT_TOKEN) &&
  2461. !IdentifierIs(t1, PROPERTY_TOKEN) )
  2462. {
  2463. RewindTo(&t1);
  2464. break;
  2465. }
  2466. }
  2467. GetToken(&t1);
  2468. RewindTo(&t);
  2469. if( t1.type == ttStartStatementBlock )
  2470. return true;
  2471. }
  2472. RewindTo(&t);
  2473. return false;
  2474. }
  2475. RewindTo(&t);
  2476. return false;
  2477. }
  2478. // BNF:1: FUNCDEF ::= {'external' | 'shared'} 'funcdef' TYPE ['&'] IDENTIFIER PARAMLIST ';'
  2479. asCScriptNode *asCParser::ParseFuncDef()
  2480. {
  2481. asCScriptNode *node = CreateNode(snFuncDef);
  2482. if( node == 0 ) return 0;
  2483. // Allow keywords 'external' and 'shared' before 'interface'
  2484. sToken t1;
  2485. GetToken(&t1);
  2486. while (IdentifierIs(t1, SHARED_TOKEN) ||
  2487. IdentifierIs(t1, EXTERNAL_TOKEN))
  2488. {
  2489. RewindTo(&t1);
  2490. node->AddChildLast(ParseIdentifier());
  2491. if (isSyntaxError) return node;
  2492. GetToken(&t1);
  2493. }
  2494. if( t1.type != ttFuncDef )
  2495. {
  2496. Error(asCTokenizer::GetDefinition(ttFuncDef), &t1);
  2497. return node;
  2498. }
  2499. node->SetToken(&t1);
  2500. node->AddChildLast(ParseType(true));
  2501. if( isSyntaxError ) return node;
  2502. node->AddChildLast(ParseTypeMod(false));
  2503. if( isSyntaxError ) return node;
  2504. node->AddChildLast(ParseIdentifier());
  2505. if( isSyntaxError ) return node;
  2506. node->AddChildLast(ParseParameterList());
  2507. if( isSyntaxError ) return node;
  2508. GetToken(&t1);
  2509. if( t1.type != ttEndStatement )
  2510. {
  2511. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEndStatement)), &t1);
  2512. Error(InsteadFound(t1), &t1);
  2513. return node;
  2514. }
  2515. node->UpdateSourcePos(t1.pos, t1.length);
  2516. return node;
  2517. }
  2518. // BNF:1: FUNC ::= {'shared' | 'external'} ['private' | 'protected'] [((TYPE ['&']) | '~')] IDENTIFIER PARAMLIST ['const'] FUNCATTR (';' | STATBLOCK)
  2519. asCScriptNode *asCParser::ParseFunction(bool isMethod)
  2520. {
  2521. asCScriptNode *node = CreateNode(snFunction);
  2522. if( node == 0 ) return 0;
  2523. sToken t1;
  2524. GetToken(&t1);
  2525. if (!isMethod)
  2526. {
  2527. // A global function can be marked as shared and external
  2528. while (t1.type == ttIdentifier)
  2529. {
  2530. if (IdentifierIs(t1, SHARED_TOKEN) ||
  2531. IdentifierIs(t1, EXTERNAL_TOKEN))
  2532. {
  2533. RewindTo(&t1);
  2534. node->AddChildLast(ParseIdentifier());
  2535. if (isSyntaxError) return node;
  2536. }
  2537. else
  2538. break;
  2539. GetToken(&t1);
  2540. }
  2541. }
  2542. // A class method can start with 'private' or 'protected'
  2543. if (isMethod && t1.type == ttPrivate)
  2544. {
  2545. RewindTo(&t1);
  2546. node->AddChildLast(ParseToken(ttPrivate));
  2547. GetToken(&t1);
  2548. }
  2549. else if (isMethod && t1.type == ttProtected)
  2550. {
  2551. RewindTo(&t1);
  2552. node->AddChildLast(ParseToken(ttProtected));
  2553. GetToken(&t1);
  2554. }
  2555. if( isSyntaxError ) return node;
  2556. // If it is a global function, or a method, except constructor and destructor, then the return type is parsed
  2557. sToken t2;
  2558. GetToken(&t2);
  2559. RewindTo(&t1);
  2560. if( !isMethod || (t1.type != ttBitNot && t2.type != ttOpenParenthesis) )
  2561. {
  2562. node->AddChildLast(ParseType(true));
  2563. if( isSyntaxError ) return node;
  2564. node->AddChildLast(ParseTypeMod(false));
  2565. if( isSyntaxError ) return node;
  2566. }
  2567. // If this is a class destructor then it starts with ~, and no return type is declared
  2568. if( isMethod && t1.type == ttBitNot )
  2569. {
  2570. node->AddChildLast(ParseToken(ttBitNot));
  2571. if( isSyntaxError ) return node;
  2572. }
  2573. node->AddChildLast(ParseIdentifier());
  2574. if( isSyntaxError ) return node;
  2575. node->AddChildLast(ParseParameterList());
  2576. if( isSyntaxError ) return node;
  2577. if( isMethod )
  2578. {
  2579. GetToken(&t1);
  2580. RewindTo(&t1);
  2581. // Is the method a const?
  2582. if( t1.type == ttConst )
  2583. node->AddChildLast(ParseToken(ttConst));
  2584. }
  2585. // TODO: Should support abstract methods, in which case no statement block should be provided
  2586. ParseMethodAttributes(node);
  2587. if( isSyntaxError ) return node;
  2588. // External shared functions must be ended with ';'
  2589. GetToken(&t1);
  2590. RewindTo(&t1);
  2591. if (t1.type == ttEndStatement)
  2592. {
  2593. node->AddChildLast(ParseToken(ttEndStatement));
  2594. return node;
  2595. }
  2596. // We should just find the end of the statement block here. The statements
  2597. // will be parsed on request by the compiler once it starts the compilation.
  2598. node->AddChildLast(SuperficiallyParseStatementBlock());
  2599. return node;
  2600. }
  2601. // BNF:2: INTFMTHD ::= TYPE ['&'] IDENTIFIER PARAMLIST ['const'] ';'
  2602. asCScriptNode *asCParser::ParseInterfaceMethod()
  2603. {
  2604. asCScriptNode *node = CreateNode(snFunction);
  2605. if( node == 0 ) return 0;
  2606. node->AddChildLast(ParseType(true));
  2607. if( isSyntaxError ) return node;
  2608. node->AddChildLast(ParseTypeMod(false));
  2609. if( isSyntaxError ) return node;
  2610. node->AddChildLast(ParseIdentifier());
  2611. if( isSyntaxError ) return node;
  2612. node->AddChildLast(ParseParameterList());
  2613. if( isSyntaxError ) return node;
  2614. // Parse an optional const after the method definition
  2615. sToken t1;
  2616. GetToken(&t1);
  2617. RewindTo(&t1);
  2618. if( t1.type == ttConst )
  2619. node->AddChildLast(ParseToken(ttConst));
  2620. GetToken(&t1);
  2621. if( t1.type != ttEndStatement )
  2622. {
  2623. Error(ExpectedToken(";"), &t1);
  2624. Error(InsteadFound(t1), &t1);
  2625. return node;
  2626. }
  2627. node->UpdateSourcePos(t1.pos, t1.length);
  2628. return node;
  2629. }
  2630. // BNF:1: VIRTPROP ::= ['private' | 'protected'] TYPE ['&'] IDENTIFIER '{' {('get' | 'set') ['const'] FUNCATTR (STATBLOCK | ';')} '}'
  2631. asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
  2632. {
  2633. asCScriptNode *node = CreateNode(snVirtualProperty);
  2634. if( node == 0 ) return 0;
  2635. sToken t1,t2;
  2636. GetToken(&t1);
  2637. GetToken(&t2);
  2638. RewindTo(&t1);
  2639. // A class method can start with 'private' or 'protected'
  2640. if( isMethod && t1.type == ttPrivate )
  2641. node->AddChildLast(ParseToken(ttPrivate));
  2642. else if( isMethod && t1.type == ttProtected )
  2643. node->AddChildLast(ParseToken(ttProtected));
  2644. if( isSyntaxError ) return node;
  2645. node->AddChildLast(ParseType(true));
  2646. if( isSyntaxError ) return node;
  2647. node->AddChildLast(ParseTypeMod(false));
  2648. if( isSyntaxError ) return node;
  2649. node->AddChildLast(ParseIdentifier());
  2650. if( isSyntaxError ) return node;
  2651. GetToken(&t1);
  2652. if( t1.type != ttStartStatementBlock )
  2653. {
  2654. Error(ExpectedToken("{"), &t1);
  2655. Error(InsteadFound(t1), &t1);
  2656. return node;
  2657. }
  2658. for(;;)
  2659. {
  2660. GetToken(&t1);
  2661. asCScriptNode *accessorNode = 0;
  2662. if( IdentifierIs(t1, GET_TOKEN) || IdentifierIs(t1, SET_TOKEN) )
  2663. {
  2664. accessorNode = CreateNode(snVirtualProperty);
  2665. if( accessorNode == 0 ) return 0;
  2666. node->AddChildLast(accessorNode);
  2667. RewindTo(&t1);
  2668. accessorNode->AddChildLast(ParseIdentifier());
  2669. if( isMethod )
  2670. {
  2671. GetToken(&t1);
  2672. RewindTo(&t1);
  2673. if( t1.type == ttConst )
  2674. accessorNode->AddChildLast(ParseToken(ttConst));
  2675. if( !isInterface )
  2676. {
  2677. ParseMethodAttributes(accessorNode);
  2678. if( isSyntaxError ) return node;
  2679. }
  2680. }
  2681. if( !isInterface )
  2682. {
  2683. GetToken(&t1);
  2684. if( t1.type == ttStartStatementBlock )
  2685. {
  2686. RewindTo(&t1);
  2687. accessorNode->AddChildLast(SuperficiallyParseStatementBlock());
  2688. if( isSyntaxError ) return node;
  2689. }
  2690. else if( t1.type != ttEndStatement )
  2691. {
  2692. Error(ExpectedTokens(";", "{"), &t1);
  2693. Error(InsteadFound(t1), &t1);
  2694. return node;
  2695. }
  2696. }
  2697. else
  2698. {
  2699. GetToken(&t1);
  2700. if( t1.type != ttEndStatement )
  2701. {
  2702. Error(ExpectedToken(";"), &t1);
  2703. Error(InsteadFound(t1), &t1);
  2704. return node;
  2705. }
  2706. }
  2707. }
  2708. else if( t1.type == ttEndStatementBlock )
  2709. break;
  2710. else
  2711. {
  2712. const char *tokens[] = { GET_TOKEN, SET_TOKEN, asCTokenizer::GetDefinition(ttEndStatementBlock) };
  2713. Error(ExpectedOneOf(tokens, 3), &t1);
  2714. Error(InsteadFound(t1), &t1);
  2715. return node;
  2716. }
  2717. }
  2718. return node;
  2719. }
  2720. // BNF:1: INTERFACE ::= {'external' | 'shared'} 'interface' IDENTIFIER (';' | ([':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | INTFMTHD} '}'))
  2721. asCScriptNode *asCParser::ParseInterface()
  2722. {
  2723. asCScriptNode *node = CreateNode(snInterface);
  2724. if( node == 0 ) return 0;
  2725. sToken t;
  2726. // Allow keywords 'external' and 'shared' before 'interface'
  2727. GetToken(&t);
  2728. while( IdentifierIs(t, SHARED_TOKEN) ||
  2729. IdentifierIs(t, EXTERNAL_TOKEN) )
  2730. {
  2731. RewindTo(&t);
  2732. node->AddChildLast(ParseIdentifier());
  2733. if (isSyntaxError) return node;
  2734. GetToken(&t);
  2735. }
  2736. if( t.type != ttInterface )
  2737. {
  2738. Error(ExpectedToken("interface"), &t);
  2739. Error(InsteadFound(t), &t);
  2740. return node;
  2741. }
  2742. node->SetToken(&t);
  2743. node->AddChildLast(ParseIdentifier());
  2744. // External shared declarations are ended with ';'
  2745. GetToken(&t);
  2746. if (t.type == ttEndStatement)
  2747. {
  2748. RewindTo(&t);
  2749. node->AddChildLast(ParseToken(ttEndStatement));
  2750. return node;
  2751. }
  2752. // Can optionally have a list of interfaces that are inherited
  2753. if( t.type == ttColon )
  2754. {
  2755. asCScriptNode *inherit = CreateNode(snIdentifier);
  2756. node->AddChildLast(inherit);
  2757. ParseOptionalScope(inherit);
  2758. inherit->AddChildLast(ParseIdentifier());
  2759. GetToken(&t);
  2760. while( t.type == ttListSeparator )
  2761. {
  2762. inherit = CreateNode(snIdentifier);
  2763. node->AddChildLast(inherit);
  2764. ParseOptionalScope(inherit);
  2765. inherit->AddChildLast(ParseIdentifier());
  2766. GetToken(&t);
  2767. }
  2768. }
  2769. if( t.type != ttStartStatementBlock )
  2770. {
  2771. Error(ExpectedToken("{"), &t);
  2772. Error(InsteadFound(t), &t);
  2773. return node;
  2774. }
  2775. // Parse interface methods
  2776. GetToken(&t);
  2777. RewindTo(&t);
  2778. while( t.type != ttEndStatementBlock && t.type != ttEnd )
  2779. {
  2780. if( IsVirtualPropertyDecl() )
  2781. node->AddChildLast(ParseVirtualPropertyDecl(true, true));
  2782. else if( t.type == ttEndStatement )
  2783. // Skip empty declarations
  2784. GetToken(&t);
  2785. else
  2786. // Parse the method signature
  2787. node->AddChildLast(ParseInterfaceMethod());
  2788. if( isSyntaxError ) return node;
  2789. GetToken(&t);
  2790. RewindTo(&t);
  2791. }
  2792. GetToken(&t);
  2793. if( t.type != ttEndStatementBlock )
  2794. {
  2795. Error(ExpectedToken("}"), &t);
  2796. Error(InsteadFound(t), &t);
  2797. return node;
  2798. }
  2799. node->UpdateSourcePos(t.pos, t.length);
  2800. return node;
  2801. }
  2802. // BNF:1: MIXIN ::= 'mixin' CLASS
  2803. asCScriptNode *asCParser::ParseMixin()
  2804. {
  2805. asCScriptNode *node = CreateNode(snMixin);
  2806. if( node == 0 ) return 0;
  2807. sToken t;
  2808. GetToken(&t);
  2809. if( t.type != ttMixin )
  2810. {
  2811. Error(ExpectedToken("mixin"), &t);
  2812. Error(InsteadFound(t), &t);
  2813. return node;
  2814. }
  2815. node->SetToken(&t);
  2816. // A mixin token must be followed by a class declaration
  2817. node->AddChildLast(ParseClass());
  2818. return node;
  2819. }
  2820. // BNF:1: CLASS ::= {'shared' | 'abstract' | 'final' | 'external'} 'class' IDENTIFIER (';' | ([':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | FUNC | VAR | FUNCDEF} '}'))
  2821. asCScriptNode *asCParser::ParseClass()
  2822. {
  2823. asCScriptNode *node = CreateNode(snClass);
  2824. if( node == 0 ) return 0;
  2825. sToken t;
  2826. GetToken(&t);
  2827. // Allow the keywords 'shared', 'abstract', 'final', and 'external' before 'class'
  2828. while( IdentifierIs(t, SHARED_TOKEN) ||
  2829. IdentifierIs(t, ABSTRACT_TOKEN) ||
  2830. IdentifierIs(t, FINAL_TOKEN) ||
  2831. IdentifierIs(t, EXTERNAL_TOKEN) )
  2832. {
  2833. RewindTo(&t);
  2834. node->AddChildLast(ParseIdentifier());
  2835. GetToken(&t);
  2836. }
  2837. if( t.type != ttClass )
  2838. {
  2839. Error(ExpectedToken("class"), &t);
  2840. Error(InsteadFound(t), &t);
  2841. return node;
  2842. }
  2843. node->SetToken(&t);
  2844. if( engine->ep.allowImplicitHandleTypes )
  2845. {
  2846. // Parse 'implicit handle class' construct
  2847. GetToken(&t);
  2848. if ( t.type == ttHandle )
  2849. node->SetToken(&t);
  2850. else
  2851. RewindTo(&t);
  2852. }
  2853. node->AddChildLast(ParseIdentifier());
  2854. // External shared declarations are ended with ';'
  2855. GetToken(&t);
  2856. if (t.type == ttEndStatement)
  2857. {
  2858. RewindTo(&t);
  2859. node->AddChildLast(ParseToken(ttEndStatement));
  2860. return node;
  2861. }
  2862. // Optional list of interfaces that are being implemented and classes that are being inherited
  2863. if( t.type == ttColon )
  2864. {
  2865. asCScriptNode *inherit = CreateNode(snIdentifier);
  2866. node->AddChildLast(inherit);
  2867. ParseOptionalScope(inherit);
  2868. inherit->AddChildLast(ParseIdentifier());
  2869. GetToken(&t);
  2870. while( t.type == ttListSeparator )
  2871. {
  2872. inherit = CreateNode(snIdentifier);
  2873. node->AddChildLast(inherit);
  2874. ParseOptionalScope(inherit);
  2875. inherit->AddChildLast(ParseIdentifier());
  2876. GetToken(&t);
  2877. }
  2878. }
  2879. if( t.type != ttStartStatementBlock )
  2880. {
  2881. Error(ExpectedToken("{"), &t);
  2882. Error(InsteadFound(t), &t);
  2883. return node;
  2884. }
  2885. // Parse properties
  2886. GetToken(&t);
  2887. RewindTo(&t);
  2888. while( t.type != ttEndStatementBlock && t.type != ttEnd )
  2889. {
  2890. // Is it a property or a method?
  2891. if (t.type == ttFuncDef)
  2892. node->AddChildLast(ParseFuncDef());
  2893. else if( IsFuncDecl(true) )
  2894. node->AddChildLast(ParseFunction(true));
  2895. else if( IsVirtualPropertyDecl() )
  2896. node->AddChildLast(ParseVirtualPropertyDecl(true, false));
  2897. else if( IsVarDecl() )
  2898. node->AddChildLast(ParseDeclaration(true));
  2899. else if( t.type == ttEndStatement )
  2900. // Skip empty declarations
  2901. GetToken(&t);
  2902. else
  2903. {
  2904. Error(TXT_EXPECTED_METHOD_OR_PROPERTY, &t);
  2905. Error(InsteadFound(t), &t);
  2906. return node;
  2907. }
  2908. if( isSyntaxError )
  2909. return node;
  2910. GetToken(&t);
  2911. RewindTo(&t);
  2912. }
  2913. GetToken(&t);
  2914. if( t.type != ttEndStatementBlock )
  2915. {
  2916. Error(ExpectedToken("}"), &t);
  2917. Error(InsteadFound(t), &t);
  2918. return node;
  2919. }
  2920. node->UpdateSourcePos(t.pos, t.length);
  2921. return node;
  2922. }
  2923. int asCParser::ParseVarInit(asCScriptCode *in_script, asCScriptNode *in_init)
  2924. {
  2925. Reset();
  2926. // Tell the parser to validate the identifiers as valid types
  2927. checkValidTypes = true;
  2928. this->script = in_script;
  2929. sourcePos = in_init->tokenPos;
  2930. // If next token is assignment, parse expression
  2931. sToken t;
  2932. GetToken(&t);
  2933. if( t.type == ttAssignment )
  2934. {
  2935. GetToken(&t);
  2936. RewindTo(&t);
  2937. if( t.type == ttStartStatementBlock )
  2938. scriptNode = ParseInitList();
  2939. else
  2940. scriptNode = ParseAssignment();
  2941. }
  2942. else if( t.type == ttOpenParenthesis)
  2943. {
  2944. RewindTo(&t);
  2945. scriptNode = ParseArgList();
  2946. }
  2947. else
  2948. {
  2949. int tokens[] = {ttAssignment, ttOpenParenthesis };
  2950. Error(ExpectedOneOf(tokens, 2), &t);
  2951. Error(InsteadFound(t), &t);
  2952. }
  2953. // Don't allow any more tokens after the expression
  2954. GetToken(&t);
  2955. if( t.type != ttEnd && t.type != ttEndStatement && t.type != ttListSeparator && t.type != ttEndStatementBlock )
  2956. {
  2957. asCString msg;
  2958. msg.Format(TXT_UNEXPECTED_TOKEN_s, asCTokenizer::GetDefinition(t.type));
  2959. Error(msg, &t);
  2960. }
  2961. if( isSyntaxError || errorWhileParsing )
  2962. return -1;
  2963. return 0;
  2964. }
  2965. asCScriptNode *asCParser::SuperficiallyParseVarInit()
  2966. {
  2967. asCScriptNode *node = CreateNode(snAssignment);
  2968. if( node == 0 ) return 0;
  2969. sToken t;
  2970. GetToken(&t);
  2971. node->UpdateSourcePos(t.pos, t.length);
  2972. if( t.type == ttAssignment )
  2973. {
  2974. GetToken(&t);
  2975. sToken start = t;
  2976. // Find the end of the expression
  2977. int indentParan = 0;
  2978. int indentBrace = 0;
  2979. while( indentParan || indentBrace || (t.type != ttListSeparator && t.type != ttEndStatement && t.type != ttEndStatementBlock) )
  2980. {
  2981. if( t.type == ttOpenParenthesis)
  2982. indentParan++;
  2983. else if( t.type == ttCloseParenthesis)
  2984. indentParan--;
  2985. else if( t.type == ttStartStatementBlock )
  2986. indentBrace++;
  2987. else if( t.type == ttEndStatementBlock )
  2988. indentBrace--;
  2989. else if( t.type == ttNonTerminatedStringConstant )
  2990. {
  2991. Error(TXT_NONTERMINATED_STRING, &t);
  2992. break;
  2993. }
  2994. else if( t.type == ttEnd )
  2995. {
  2996. Error(TXT_UNEXPECTED_END_OF_FILE, &t);
  2997. Info(TXT_WHILE_PARSING_EXPRESSION, &start);
  2998. break;
  2999. }
  3000. GetToken(&t);
  3001. }
  3002. // Rewind so that the next token read is the list separator, end statement, or end statement block
  3003. RewindTo(&t);
  3004. }
  3005. else if( t.type == ttOpenParenthesis)
  3006. {
  3007. sToken start = t;
  3008. // Find the end of the argument list
  3009. int indent = 1;
  3010. while( indent )
  3011. {
  3012. GetToken(&t);
  3013. if( t.type == ttOpenParenthesis)
  3014. indent++;
  3015. else if( t.type == ttCloseParenthesis)
  3016. indent--;
  3017. else if( t.type == ttNonTerminatedStringConstant )
  3018. {
  3019. Error(TXT_NONTERMINATED_STRING, &t);
  3020. break;
  3021. }
  3022. else if( t.type == ttEnd )
  3023. {
  3024. Error(TXT_UNEXPECTED_END_OF_FILE, &t);
  3025. Info(TXT_WHILE_PARSING_ARG_LIST, &start);
  3026. break;
  3027. }
  3028. }
  3029. }
  3030. else
  3031. {
  3032. int tokens[] = {ttAssignment, ttOpenParenthesis };
  3033. Error(ExpectedOneOf(tokens, 2), &t);
  3034. Error(InsteadFound(t), &t);
  3035. }
  3036. return node;
  3037. }
  3038. asCScriptNode *asCParser::SuperficiallyParseStatementBlock()
  3039. {
  3040. asCScriptNode *node = CreateNode(snStatementBlock);
  3041. if( node == 0 ) return 0;
  3042. // This function will only superficially parse the statement block in order to find the end of it
  3043. sToken t1;
  3044. GetToken(&t1);
  3045. if( t1.type != ttStartStatementBlock )
  3046. {
  3047. Error(ExpectedToken("{"), &t1);
  3048. Error(InsteadFound(t1), &t1);
  3049. return node;
  3050. }
  3051. node->UpdateSourcePos(t1.pos, t1.length);
  3052. sToken start = t1;
  3053. int level = 1;
  3054. while( level > 0 && !isSyntaxError )
  3055. {
  3056. GetToken(&t1);
  3057. if( t1.type == ttEndStatementBlock )
  3058. level--;
  3059. else if( t1.type == ttStartStatementBlock )
  3060. level++;
  3061. else if( t1.type == ttNonTerminatedStringConstant )
  3062. {
  3063. Error(TXT_NONTERMINATED_STRING, &t1);
  3064. break;
  3065. }
  3066. else if( t1.type == ttEnd )
  3067. {
  3068. Error(TXT_UNEXPECTED_END_OF_FILE, &t1);
  3069. Info(TXT_WHILE_PARSING_STATEMENT_BLOCK, &start);
  3070. break;
  3071. }
  3072. }
  3073. node->UpdateSourcePos(t1.pos, t1.length);
  3074. return node;
  3075. }
  3076. // BNF:2: STATBLOCK ::= '{' {VAR | STATEMENT} '}'
  3077. asCScriptNode *asCParser::ParseStatementBlock()
  3078. {
  3079. asCScriptNode *node = CreateNode(snStatementBlock);
  3080. if( node == 0 ) return 0;
  3081. sToken t1;
  3082. GetToken(&t1);
  3083. if( t1.type != ttStartStatementBlock )
  3084. {
  3085. Error(ExpectedToken("{"), &t1);
  3086. Error(InsteadFound(t1), &t1);
  3087. return node;
  3088. }
  3089. sToken start = t1;
  3090. node->UpdateSourcePos(t1.pos, t1.length);
  3091. for(;;)
  3092. {
  3093. while( !isSyntaxError )
  3094. {
  3095. GetToken(&t1);
  3096. if( t1.type == ttEndStatementBlock )
  3097. {
  3098. node->UpdateSourcePos(t1.pos, t1.length);
  3099. // Statement block is finished
  3100. return node;
  3101. }
  3102. else
  3103. {
  3104. RewindTo(&t1);
  3105. if( IsVarDecl() )
  3106. node->AddChildLast(ParseDeclaration());
  3107. else
  3108. node->AddChildLast(ParseStatement());
  3109. }
  3110. }
  3111. if( isSyntaxError )
  3112. {
  3113. // Search for either ';', '{', '}', or end
  3114. GetToken(&t1);
  3115. while( t1.type != ttEndStatement && t1.type != ttEnd &&
  3116. t1.type != ttStartStatementBlock && t1.type != ttEndStatementBlock )
  3117. {
  3118. GetToken(&t1);
  3119. }
  3120. // Skip this statement block
  3121. if( t1.type == ttStartStatementBlock )
  3122. {
  3123. // Find the end of the block and skip nested blocks
  3124. int level = 1;
  3125. while( level > 0 )
  3126. {
  3127. GetToken(&t1);
  3128. if( t1.type == ttStartStatementBlock ) level++;
  3129. if( t1.type == ttEndStatementBlock ) level--;
  3130. if( t1.type == ttEnd ) break;
  3131. }
  3132. }
  3133. else if( t1.type == ttEndStatementBlock )
  3134. {
  3135. RewindTo(&t1);
  3136. }
  3137. else if( t1.type == ttEnd )
  3138. {
  3139. Error(TXT_UNEXPECTED_END_OF_FILE, &t1);
  3140. Info(TXT_WHILE_PARSING_STATEMENT_BLOCK, &start);
  3141. return node;
  3142. }
  3143. isSyntaxError = false;
  3144. }
  3145. }
  3146. UNREACHABLE_RETURN;
  3147. }
  3148. // BNF:4: INITLIST ::= '{' [ASSIGN | INITLIST] {',' [ASSIGN | INITLIST]} '}'
  3149. asCScriptNode *asCParser::ParseInitList()
  3150. {
  3151. asCScriptNode *node = CreateNode(snInitList);
  3152. if( node == 0 ) return 0;
  3153. sToken t1;
  3154. GetToken(&t1);
  3155. if( t1.type != ttStartStatementBlock )
  3156. {
  3157. Error(ExpectedToken("{"), &t1);
  3158. Error(InsteadFound(t1), &t1);
  3159. return node;
  3160. }
  3161. node->UpdateSourcePos(t1.pos, t1.length);
  3162. GetToken(&t1);
  3163. if( t1.type == ttEndStatementBlock )
  3164. {
  3165. node->UpdateSourcePos(t1.pos, t1.length);
  3166. // Statement block is finished
  3167. return node;
  3168. }
  3169. else
  3170. {
  3171. RewindTo(&t1);
  3172. for(;;)
  3173. {
  3174. GetToken(&t1);
  3175. if( t1.type == ttListSeparator )
  3176. {
  3177. // No expression
  3178. node->AddChildLast(CreateNode(snUndefined));
  3179. node->lastChild->UpdateSourcePos(t1.pos, 1);
  3180. GetToken(&t1);
  3181. if( t1.type == ttEndStatementBlock )
  3182. {
  3183. // No expression
  3184. node->AddChildLast(CreateNode(snUndefined));
  3185. node->lastChild->UpdateSourcePos(t1.pos, 1);
  3186. node->UpdateSourcePos(t1.pos, t1.length);
  3187. return node;
  3188. }
  3189. RewindTo(&t1);
  3190. }
  3191. else if( t1.type == ttEndStatementBlock )
  3192. {
  3193. // No expression
  3194. node->AddChildLast(CreateNode(snUndefined));
  3195. node->lastChild->UpdateSourcePos(t1.pos, 1);
  3196. node->UpdateSourcePos(t1.pos, t1.length);
  3197. // Statement block is finished
  3198. return node;
  3199. }
  3200. else if( t1.type == ttStartStatementBlock )
  3201. {
  3202. RewindTo(&t1);
  3203. node->AddChildLast(ParseInitList());
  3204. if( isSyntaxError ) return node;
  3205. GetToken(&t1);
  3206. if( t1.type == ttListSeparator )
  3207. continue;
  3208. else if( t1.type == ttEndStatementBlock )
  3209. {
  3210. node->UpdateSourcePos(t1.pos, t1.length);
  3211. // Statement block is finished
  3212. return node;
  3213. }
  3214. else
  3215. {
  3216. Error(ExpectedTokens("}", ","), &t1);
  3217. Error(InsteadFound(t1), &t1);
  3218. return node;
  3219. }
  3220. }
  3221. else
  3222. {
  3223. RewindTo(&t1);
  3224. node->AddChildLast(ParseAssignment());
  3225. if( isSyntaxError ) return node;
  3226. GetToken(&t1);
  3227. if( t1.type == ttListSeparator )
  3228. continue;
  3229. else if( t1.type == ttEndStatementBlock )
  3230. {
  3231. node->UpdateSourcePos(t1.pos, t1.length);
  3232. // Statement block is finished
  3233. return node;
  3234. }
  3235. else
  3236. {
  3237. Error(ExpectedTokens("}", ","), &t1);
  3238. Error(InsteadFound(t1), &t1);
  3239. return node;
  3240. }
  3241. }
  3242. }
  3243. }
  3244. UNREACHABLE_RETURN;
  3245. }
  3246. // BNF:1: VAR ::= ['private'|'protected'] TYPE IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST] {',' IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST]} ';'
  3247. asCScriptNode *asCParser::ParseDeclaration(bool isClassProp, bool isGlobalVar)
  3248. {
  3249. asCScriptNode *node = CreateNode(snDeclaration);
  3250. if( node == 0 ) return 0;
  3251. sToken t;
  3252. GetToken(&t);
  3253. RewindTo(&t);
  3254. // A class property can be preceeded by private
  3255. if( t.type == ttPrivate && isClassProp )
  3256. node->AddChildLast(ParseToken(ttPrivate));
  3257. else if( t.type == ttProtected && isClassProp )
  3258. node->AddChildLast(ParseToken(ttProtected));
  3259. // Parse data type
  3260. node->AddChildLast(ParseType(true, false, !isClassProp));
  3261. if( isSyntaxError ) return node;
  3262. for(;;)
  3263. {
  3264. // Parse identifier
  3265. node->AddChildLast(ParseIdentifier());
  3266. if( isSyntaxError ) return node;
  3267. if( isClassProp || isGlobalVar )
  3268. {
  3269. // Only superficially parse the initialization info for the class property
  3270. GetToken(&t);
  3271. RewindTo(&t);
  3272. if( t.type == ttAssignment || t.type == ttOpenParenthesis)
  3273. {
  3274. node->AddChildLast(SuperficiallyParseVarInit());
  3275. if( isSyntaxError ) return node;
  3276. }
  3277. }
  3278. else
  3279. {
  3280. // If next token is assignment, parse expression
  3281. GetToken(&t);
  3282. if( t.type == ttOpenParenthesis)
  3283. {
  3284. RewindTo(&t);
  3285. node->AddChildLast(ParseArgList());
  3286. if( isSyntaxError ) return node;
  3287. }
  3288. else if( t.type == ttAssignment )
  3289. {
  3290. GetToken(&t);
  3291. RewindTo(&t);
  3292. if( t.type == ttStartStatementBlock )
  3293. {
  3294. node->AddChildLast(ParseInitList());
  3295. if( isSyntaxError ) return node;
  3296. }
  3297. else
  3298. {
  3299. node->AddChildLast(ParseAssignment());
  3300. if( isSyntaxError ) return node;
  3301. }
  3302. }
  3303. else
  3304. RewindTo(&t);
  3305. }
  3306. // continue if list separator, else terminate with end statement
  3307. GetToken(&t);
  3308. if( t.type == ttListSeparator )
  3309. continue;
  3310. else if( t.type == ttEndStatement )
  3311. {
  3312. node->UpdateSourcePos(t.pos, t.length);
  3313. return node;
  3314. }
  3315. else
  3316. {
  3317. Error(ExpectedTokens(",", ";"), &t);
  3318. Error(InsteadFound(t), &t);
  3319. return node;
  3320. }
  3321. }
  3322. UNREACHABLE_RETURN;
  3323. }
  3324. // BNF:7: STATEMENT ::= (IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPRSTAT | TRY)
  3325. asCScriptNode *asCParser::ParseStatement()
  3326. {
  3327. sToken t1;
  3328. GetToken(&t1);
  3329. RewindTo(&t1);
  3330. if (t1.type == ttIf)
  3331. return ParseIf();
  3332. else if (t1.type == ttFor)
  3333. return ParseFor();
  3334. else if (t1.type == ttWhile)
  3335. return ParseWhile();
  3336. else if (t1.type == ttReturn)
  3337. return ParseReturn();
  3338. else if (t1.type == ttStartStatementBlock)
  3339. return ParseStatementBlock();
  3340. else if (t1.type == ttBreak)
  3341. return ParseBreak();
  3342. else if (t1.type == ttContinue)
  3343. return ParseContinue();
  3344. else if (t1.type == ttDo)
  3345. return ParseDoWhile();
  3346. else if (t1.type == ttSwitch)
  3347. return ParseSwitch();
  3348. else if (t1.type == ttTry)
  3349. return ParseTryCatch();
  3350. else
  3351. {
  3352. if( IsVarDecl() )
  3353. {
  3354. Error(TXT_UNEXPECTED_VAR_DECL, &t1);
  3355. return 0;
  3356. }
  3357. return ParseExpressionStatement();
  3358. }
  3359. }
  3360. // BNF:8: EXPRSTAT ::= [ASSIGN] ';'
  3361. asCScriptNode *asCParser::ParseExpressionStatement()
  3362. {
  3363. asCScriptNode *node = CreateNode(snExpressionStatement);
  3364. if( node == 0 ) return 0;
  3365. sToken t;
  3366. GetToken(&t);
  3367. if( t.type == ttEndStatement )
  3368. {
  3369. node->UpdateSourcePos(t.pos, t.length);
  3370. return node;
  3371. }
  3372. RewindTo(&t);
  3373. node->AddChildLast(ParseAssignment());
  3374. if( isSyntaxError ) return node;
  3375. GetToken(&t);
  3376. if( t.type != ttEndStatement )
  3377. {
  3378. Error(ExpectedToken(";"), &t);
  3379. Error(InsteadFound(t), &t);
  3380. return node;
  3381. }
  3382. node->UpdateSourcePos(t.pos, t.length);
  3383. return node;
  3384. }
  3385. // BNF:8: SWITCH ::= 'switch' '(' ASSIGN ')' '{' {CASE} '}'
  3386. asCScriptNode *asCParser::ParseSwitch()
  3387. {
  3388. asCScriptNode *node = CreateNode(snSwitch);
  3389. if( node == 0 ) return 0;
  3390. sToken t;
  3391. GetToken(&t);
  3392. if( t.type != ttSwitch )
  3393. {
  3394. Error(ExpectedToken("switch"), &t);
  3395. Error(InsteadFound(t), &t);
  3396. return node;
  3397. }
  3398. node->UpdateSourcePos(t.pos, t.length);
  3399. GetToken(&t);
  3400. if( t.type != ttOpenParenthesis)
  3401. {
  3402. Error(ExpectedToken("("), &t);
  3403. Error(InsteadFound(t), &t);
  3404. return node;
  3405. }
  3406. node->AddChildLast(ParseAssignment());
  3407. if( isSyntaxError ) return node;
  3408. GetToken(&t);
  3409. if( t.type != ttCloseParenthesis)
  3410. {
  3411. Error(ExpectedToken(")"), &t);
  3412. Error(InsteadFound(t), &t);
  3413. return node;
  3414. }
  3415. GetToken(&t);
  3416. if( t.type != ttStartStatementBlock )
  3417. {
  3418. Error(ExpectedToken("{"), &t);
  3419. Error(InsteadFound(t), &t);
  3420. return node;
  3421. }
  3422. while( !isSyntaxError )
  3423. {
  3424. GetToken(&t);
  3425. if( t.type == ttEndStatementBlock )
  3426. break;
  3427. RewindTo(&t);
  3428. if( t.type != ttCase && t.type != ttDefault )
  3429. {
  3430. const char *tokens[] = {"case", "default"};
  3431. Error(ExpectedOneOf(tokens, 2), &t);
  3432. Error(InsteadFound(t), &t);
  3433. return node;
  3434. }
  3435. node->AddChildLast(ParseCase());
  3436. if( isSyntaxError ) return node;
  3437. }
  3438. if( t.type != ttEndStatementBlock )
  3439. {
  3440. Error(ExpectedToken("}"), &t);
  3441. Error(InsteadFound(t), &t);
  3442. return node;
  3443. }
  3444. return node;
  3445. }
  3446. // BNF:9: CASE ::= (('case' EXPR) | 'default') ':' {STATEMENT}
  3447. asCScriptNode *asCParser::ParseCase()
  3448. {
  3449. asCScriptNode *node = CreateNode(snCase);
  3450. if( node == 0 ) return 0;
  3451. sToken t;
  3452. GetToken(&t);
  3453. if( t.type != ttCase && t.type != ttDefault )
  3454. {
  3455. Error(ExpectedTokens("case", "default"), &t);
  3456. Error(InsteadFound(t), &t);
  3457. return node;
  3458. }
  3459. node->UpdateSourcePos(t.pos, t.length);
  3460. if(t.type == ttCase)
  3461. {
  3462. node->AddChildLast(ParseExpression());
  3463. }
  3464. GetToken(&t);
  3465. if( t.type != ttColon )
  3466. {
  3467. Error(ExpectedToken(":"), &t);
  3468. Error(InsteadFound(t), &t);
  3469. return node;
  3470. }
  3471. // Parse statements until we find either of }, case, default, and break
  3472. GetToken(&t);
  3473. RewindTo(&t);
  3474. while( t.type != ttCase &&
  3475. t.type != ttDefault &&
  3476. t.type != ttEndStatementBlock &&
  3477. t.type != ttBreak )
  3478. {
  3479. if( IsVarDecl() )
  3480. // Variable declarations are not allowed, but we parse it anyway to give a good error message
  3481. node->AddChildLast(ParseDeclaration());
  3482. else
  3483. node->AddChildLast(ParseStatement());
  3484. if( isSyntaxError ) return node;
  3485. GetToken(&t);
  3486. RewindTo(&t);
  3487. }
  3488. // If the case was ended with a break statement, add it to the node
  3489. if( t.type == ttBreak )
  3490. node->AddChildLast(ParseBreak());
  3491. return node;
  3492. }
  3493. // BNF:8: IF ::= 'if' '(' ASSIGN ')' STATEMENT ['else' STATEMENT]
  3494. asCScriptNode *asCParser::ParseIf()
  3495. {
  3496. asCScriptNode *node = CreateNode(snIf);
  3497. if( node == 0 ) return 0;
  3498. sToken t;
  3499. GetToken(&t);
  3500. if( t.type != ttIf )
  3501. {
  3502. Error(ExpectedToken("if"), &t);
  3503. Error(InsteadFound(t), &t);
  3504. return node;
  3505. }
  3506. node->UpdateSourcePos(t.pos, t.length);
  3507. GetToken(&t);
  3508. if( t.type != ttOpenParenthesis)
  3509. {
  3510. Error(ExpectedToken("("), &t);
  3511. Error(InsteadFound(t), &t);
  3512. return node;
  3513. }
  3514. node->AddChildLast(ParseAssignment());
  3515. if( isSyntaxError ) return node;
  3516. GetToken(&t);
  3517. if( t.type != ttCloseParenthesis)
  3518. {
  3519. Error(ExpectedToken(")"), &t);
  3520. Error(InsteadFound(t), &t);
  3521. return node;
  3522. }
  3523. node->AddChildLast(ParseStatement());
  3524. if( isSyntaxError ) return node;
  3525. GetToken(&t);
  3526. if( t.type != ttElse )
  3527. {
  3528. // No else statement return already
  3529. RewindTo(&t);
  3530. return node;
  3531. }
  3532. node->AddChildLast(ParseStatement());
  3533. return node;
  3534. }
  3535. // BNF:8: TRY ::= 'try' STATBLOCK 'catch' STATBLOCK
  3536. asCScriptNode *asCParser::ParseTryCatch()
  3537. {
  3538. asCScriptNode *node = CreateNode(snTryCatch);
  3539. if (node == 0) return 0;
  3540. sToken t;
  3541. GetToken(&t);
  3542. if (t.type != ttTry)
  3543. {
  3544. Error(ExpectedToken("try"), &t);
  3545. Error(InsteadFound(t), &t);
  3546. return node;
  3547. }
  3548. node->UpdateSourcePos(t.pos, t.length);
  3549. node->AddChildLast(ParseStatementBlock());
  3550. if (isSyntaxError) return node;
  3551. GetToken(&t);
  3552. if (t.type != ttCatch)
  3553. {
  3554. Error(ExpectedToken("catch"), &t);
  3555. Error(InsteadFound(t), &t);
  3556. return node;
  3557. }
  3558. node->AddChildLast(ParseStatementBlock());
  3559. if (isSyntaxError) return node;
  3560. return node;
  3561. }
  3562. // BNF:8: FOR ::= 'for' '(' (VAR | EXPRSTAT) EXPRSTAT [ASSIGN {',' ASSIGN}] ')' STATEMENT
  3563. asCScriptNode *asCParser::ParseFor()
  3564. {
  3565. asCScriptNode *node = CreateNode(snFor);
  3566. if( node == 0 ) return 0;
  3567. sToken t;
  3568. GetToken(&t);
  3569. if( t.type != ttFor )
  3570. {
  3571. Error(ExpectedToken("for"), &t);
  3572. Error(InsteadFound(t), &t);
  3573. return node;
  3574. }
  3575. node->UpdateSourcePos(t.pos, t.length);
  3576. GetToken(&t);
  3577. if( t.type != ttOpenParenthesis)
  3578. {
  3579. Error(ExpectedToken("("), &t);
  3580. Error(InsteadFound(t), &t);
  3581. return node;
  3582. }
  3583. if( IsVarDecl() )
  3584. node->AddChildLast(ParseDeclaration());
  3585. else
  3586. node->AddChildLast(ParseExpressionStatement());
  3587. if( isSyntaxError ) return node;
  3588. node->AddChildLast(ParseExpressionStatement());
  3589. if( isSyntaxError ) return node;
  3590. GetToken(&t);
  3591. if( t.type != ttCloseParenthesis)
  3592. {
  3593. RewindTo(&t);
  3594. // Parse N increment statements separated by ,
  3595. for(;;)
  3596. {
  3597. asCScriptNode *n = CreateNode(snExpressionStatement);
  3598. if( n == 0 ) return 0;
  3599. node->AddChildLast(n);
  3600. n->AddChildLast(ParseAssignment());
  3601. if( isSyntaxError ) return node;
  3602. GetToken(&t);
  3603. if( t.type == ttListSeparator )
  3604. continue;
  3605. else if( t.type == ttCloseParenthesis)
  3606. break;
  3607. else
  3608. {
  3609. const char *tokens[] = {",", ")"};
  3610. Error(ExpectedOneOf(tokens, 2), &t);
  3611. Error(InsteadFound(t), &t);
  3612. return node;
  3613. }
  3614. }
  3615. }
  3616. node->AddChildLast(ParseStatement());
  3617. return node;
  3618. }
  3619. // BNF:8: WHILE ::= 'while' '(' ASSIGN ')' STATEMENT
  3620. asCScriptNode *asCParser::ParseWhile()
  3621. {
  3622. asCScriptNode *node = CreateNode(snWhile);
  3623. if( node == 0 ) return 0;
  3624. sToken t;
  3625. GetToken(&t);
  3626. if( t.type != ttWhile )
  3627. {
  3628. Error(ExpectedToken("while"), &t);
  3629. Error(InsteadFound(t), &t);
  3630. return node;
  3631. }
  3632. node->UpdateSourcePos(t.pos, t.length);
  3633. GetToken(&t);
  3634. if( t.type != ttOpenParenthesis)
  3635. {
  3636. Error(ExpectedToken("("), &t);
  3637. Error(InsteadFound(t), &t);
  3638. return node;
  3639. }
  3640. node->AddChildLast(ParseAssignment());
  3641. if( isSyntaxError ) return node;
  3642. GetToken(&t);
  3643. if( t.type != ttCloseParenthesis)
  3644. {
  3645. Error(ExpectedToken(")"), &t);
  3646. Error(InsteadFound(t), &t);
  3647. return node;
  3648. }
  3649. node->AddChildLast(ParseStatement());
  3650. return node;
  3651. }
  3652. // BNF:8: DOWHILE ::= 'do' STATEMENT 'while' '(' ASSIGN ')' ';'
  3653. asCScriptNode *asCParser::ParseDoWhile()
  3654. {
  3655. asCScriptNode *node = CreateNode(snDoWhile);
  3656. if( node == 0 ) return 0;
  3657. sToken t;
  3658. GetToken(&t);
  3659. if( t.type != ttDo )
  3660. {
  3661. Error(ExpectedToken("do"), &t);
  3662. Error(InsteadFound(t), &t);
  3663. return node;
  3664. }
  3665. node->UpdateSourcePos(t.pos, t.length);
  3666. node->AddChildLast(ParseStatement());
  3667. if( isSyntaxError ) return node;
  3668. GetToken(&t);
  3669. if( t.type != ttWhile )
  3670. {
  3671. Error(ExpectedToken("while"), &t);
  3672. Error(InsteadFound(t), &t);
  3673. return node;
  3674. }
  3675. GetToken(&t);
  3676. if( t.type != ttOpenParenthesis)
  3677. {
  3678. Error(ExpectedToken("("), &t);
  3679. Error(InsteadFound(t), &t);
  3680. return node;
  3681. }
  3682. node->AddChildLast(ParseAssignment());
  3683. if( isSyntaxError ) return node;
  3684. GetToken(&t);
  3685. if( t.type != ttCloseParenthesis)
  3686. {
  3687. Error(ExpectedToken(")"), &t);
  3688. Error(InsteadFound(t), &t);
  3689. return node;
  3690. }
  3691. GetToken(&t);
  3692. if( t.type != ttEndStatement )
  3693. {
  3694. Error(ExpectedToken(";"), &t);
  3695. Error(InsteadFound(t), &t);
  3696. return node;
  3697. }
  3698. node->UpdateSourcePos(t.pos, t.length);
  3699. return node;
  3700. }
  3701. // BNF:8: RETURN ::= 'return' [ASSIGN] ';'
  3702. asCScriptNode *asCParser::ParseReturn()
  3703. {
  3704. asCScriptNode *node = CreateNode(snReturn);
  3705. if( node == 0 ) return 0;
  3706. sToken t;
  3707. GetToken(&t);
  3708. if( t.type != ttReturn )
  3709. {
  3710. Error(ExpectedToken("return"), &t);
  3711. Error(InsteadFound(t), &t);
  3712. return node;
  3713. }
  3714. node->UpdateSourcePos(t.pos, t.length);
  3715. GetToken(&t);
  3716. if( t.type == ttEndStatement )
  3717. {
  3718. node->UpdateSourcePos(t.pos, t.length);
  3719. return node;
  3720. }
  3721. RewindTo(&t);
  3722. node->AddChildLast(ParseAssignment());
  3723. if( isSyntaxError ) return node;
  3724. GetToken(&t);
  3725. if( t.type != ttEndStatement )
  3726. {
  3727. Error(ExpectedToken(";"), &t);
  3728. Error(InsteadFound(t), &t);
  3729. return node;
  3730. }
  3731. node->UpdateSourcePos(t.pos, t.length);
  3732. return node;
  3733. }
  3734. // BNF:8: BREAK ::= 'break' ';'
  3735. asCScriptNode *asCParser::ParseBreak()
  3736. {
  3737. asCScriptNode *node = CreateNode(snBreak);
  3738. if( node == 0 ) return 0;
  3739. sToken t;
  3740. GetToken(&t);
  3741. if( t.type != ttBreak )
  3742. {
  3743. Error(ExpectedToken("break"), &t);
  3744. Error(InsteadFound(t), &t);
  3745. return node;
  3746. }
  3747. node->UpdateSourcePos(t.pos, t.length);
  3748. GetToken(&t);
  3749. if( t.type != ttEndStatement )
  3750. {
  3751. Error(ExpectedToken(";"), &t);
  3752. Error(InsteadFound(t), &t);
  3753. }
  3754. node->UpdateSourcePos(t.pos, t.length);
  3755. return node;
  3756. }
  3757. // BNF:8: CONTINUE ::= 'continue' ';'
  3758. asCScriptNode *asCParser::ParseContinue()
  3759. {
  3760. asCScriptNode *node = CreateNode(snContinue);
  3761. if( node == 0 ) return 0;
  3762. sToken t;
  3763. GetToken(&t);
  3764. if( t.type != ttContinue )
  3765. {
  3766. Error(ExpectedToken("continue"), &t);
  3767. Error(InsteadFound(t), &t);
  3768. return node;
  3769. }
  3770. node->UpdateSourcePos(t.pos, t.length);
  3771. GetToken(&t);
  3772. if( t.type != ttEndStatement )
  3773. {
  3774. Error(ExpectedToken(";"), &t);
  3775. Error(InsteadFound(t), &t);
  3776. }
  3777. node->UpdateSourcePos(t.pos, t.length);
  3778. return node;
  3779. }
  3780. // TODO: typedef: Typedefs should accept complex types as well
  3781. // BNF:1: TYPEDEF ::= 'typedef' PRIMTYPE IDENTIFIER ';'
  3782. asCScriptNode *asCParser::ParseTypedef()
  3783. {
  3784. // Create the typedef node
  3785. asCScriptNode *node = CreateNode(snTypedef);
  3786. if( node == 0 ) return 0;
  3787. sToken token;
  3788. GetToken(&token);
  3789. if( token.type != ttTypedef)
  3790. {
  3791. Error(ExpectedToken(asCTokenizer::GetDefinition(ttTypedef)), &token);
  3792. Error(InsteadFound(token), &token);
  3793. return node;
  3794. }
  3795. node->SetToken(&token);
  3796. node->UpdateSourcePos(token.pos, token.length);
  3797. // Parse the base type
  3798. GetToken(&token);
  3799. RewindTo(&token);
  3800. // Make sure it is a primitive type (except ttVoid)
  3801. if( !IsRealType(token.type) || token.type == ttVoid )
  3802. {
  3803. asCString str;
  3804. str.Format(TXT_UNEXPECTED_TOKEN_s, asCTokenizer::GetDefinition(token.type));
  3805. Error(str, &token);
  3806. return node;
  3807. }
  3808. node->AddChildLast(ParseRealType());
  3809. node->AddChildLast(ParseIdentifier());
  3810. // Check for the end of the typedef
  3811. GetToken(&token);
  3812. if( token.type != ttEndStatement )
  3813. {
  3814. RewindTo(&token);
  3815. Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)), &token);
  3816. Error(InsteadFound(token), &token);
  3817. }
  3818. return node;
  3819. }
  3820. #endif
  3821. END_AS_NAMESPACE