as_parser.cpp 93 KB

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