parser.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. #include "std.h"
  2. #include <cstdlib>
  3. #include "parser.h"
  4. #ifdef DEMO
  5. static const int TEXTLIMIT=16384;
  6. #else
  7. static const int TEXTLIMIT=1024*1024-1;
  8. #endif
  9. enum{
  10. STMTS_PROG,STMTS_BLOCK,STMTS_LINE
  11. };
  12. static bool isTerm( int c ){ return c==':' || c=='\n'; }
  13. Parser::Parser( Toker &t ):toker(&t),main_toker(&t){
  14. }
  15. ProgNode *Parser::parse( const string &main ){
  16. incfile=main;
  17. consts=d_new DeclSeqNode();
  18. structs=d_new DeclSeqNode();
  19. funcs=d_new DeclSeqNode();
  20. datas=d_new DeclSeqNode();
  21. StmtSeqNode *stmts=0;
  22. try{
  23. stmts=parseStmtSeq( STMTS_PROG );
  24. if( toker->curr()!=EOF ) exp( "end-of-file" );
  25. }catch( Ex ){
  26. delete stmts;delete datas;delete funcs;delete structs;delete consts;
  27. throw;
  28. }
  29. return d_new ProgNode( consts,structs,funcs,datas,stmts );
  30. }
  31. void Parser::ex( const string &s ){
  32. throw Ex( s,toker->pos(),incfile );
  33. }
  34. void Parser::exp( const string &s ){
  35. switch( toker->curr() ){
  36. case NEXT:ex( "'Next' without 'For'" );
  37. case WEND:ex( "'Wend' without 'While'" );
  38. case ELSE:case ELSEIF:ex( "'Else' without 'If'" );
  39. case ENDIF:ex( "'Endif' without 'If'" );
  40. case ENDFUNCTION:ex( "'End Function' without 'Function'" );
  41. case UNTIL:ex( "'Until' without 'Repeat'" );
  42. case FOREVER:ex( "'Forever' without 'Repeat'" );
  43. case CASE:ex( "'Case' without 'Select'" );
  44. case ENDSELECT:ex( "'End Select' without 'Select'" );
  45. }
  46. ex( "Expecting "+s );
  47. }
  48. string Parser::parseIdent(){
  49. if( toker->curr()!=IDENT ) exp( "identifier" );
  50. string t=toker->text();
  51. toker->next();
  52. return t;
  53. }
  54. void Parser::parseChar( int c ){
  55. if( toker->curr()!=c ) exp( string( "'" )+char(c)+string( "'" ) );
  56. toker->next();
  57. }
  58. StmtSeqNode *Parser::parseStmtSeq( int scope ){
  59. a_ptr<StmtSeqNode> stmts( d_new StmtSeqNode( incfile ) );
  60. parseStmtSeq( stmts,scope );
  61. return stmts.release();
  62. }
  63. void Parser::parseStmtSeq( StmtSeqNode *stmts,int scope ){
  64. for(;;){
  65. while( toker->curr()==':' || (scope!=STMTS_LINE && toker->curr()=='\n') ) toker->next();
  66. StmtNode *result=0;
  67. int pos=toker->pos();
  68. #ifdef DEMO
  69. if( Toker::chars_toked>TEXTLIMIT ){
  70. ex( "Demo version source limit exceeded" );
  71. }
  72. #endif
  73. switch( toker->curr() ){
  74. case INCLUDE:
  75. {
  76. if( toker->next()!=STRINGCONST ) exp( "include filename" );
  77. string inc=toker->text();toker->next();
  78. inc=inc.substr( 1,inc.size()-2 );
  79. //WIN32 KLUDGE//
  80. char buff[MAX_PATH],*p;
  81. if( GetFullPathName( inc.c_str(),MAX_PATH,buff,&p ) ) inc=buff;
  82. inc=tolower(inc);
  83. if( included.find( inc )!=included.end() ) break;
  84. ifstream i_stream( inc.c_str() );
  85. if( !i_stream.good() ) ex( "Unable to open include file" );
  86. Toker i_toker( i_stream );
  87. string t_inc=incfile;incfile=inc;
  88. Toker *t_toker=toker;toker=&i_toker;
  89. included.insert( incfile );
  90. a_ptr<StmtSeqNode> ss( parseStmtSeq( scope ) );
  91. if( toker->curr()!=EOF ) exp( "end-of-file" );
  92. result=d_new IncludeNode( incfile,ss.release() );
  93. toker=t_toker;
  94. incfile=t_inc;
  95. }
  96. break;
  97. case IDENT:
  98. {
  99. string ident=toker->text();
  100. toker->next();string tag=parseTypeTag();
  101. if( arrayDecls.find(ident)==arrayDecls.end()
  102. && toker->curr()!='=' && toker->curr()!='\\' && toker->curr()!='[' ){
  103. //must be a function
  104. ExprSeqNode *exprs;
  105. if( toker->curr()=='(' ){
  106. //ugly lookahead for optional '()' around statement params
  107. int nest=1,k;
  108. for( k=1;;++k ){
  109. int c=toker->lookAhead( k );
  110. if( isTerm( c ) ) ex( "Mismatched brackets" );
  111. else if( c=='(' ) ++nest;
  112. else if( c==')' && !--nest ) break;
  113. }
  114. if( isTerm( toker->lookAhead( ++k ) ) ){
  115. toker->next();
  116. exprs=parseExprSeq();
  117. if( toker->curr()!=')' ) exp( "')'" );
  118. toker->next();
  119. }else exprs=parseExprSeq();
  120. }else exprs=parseExprSeq();
  121. CallNode *call=d_new CallNode( ident,tag,exprs );
  122. result=d_new ExprStmtNode( call );
  123. }else{
  124. //must be a var
  125. a_ptr<VarNode> var( parseVar( ident,tag ) );
  126. if( toker->curr()!='=' ) exp( "variable assignment" );
  127. toker->next();ExprNode *expr=parseExpr( false );
  128. result=d_new AssNode( var.release(),expr );
  129. }
  130. }
  131. break;
  132. case IF:
  133. {
  134. toker->next();result=parseIf();
  135. if( toker->curr()==ENDIF ) toker->next();
  136. }
  137. break;
  138. case WHILE:
  139. {
  140. toker->next();
  141. a_ptr<ExprNode> expr( parseExpr( false ) );
  142. a_ptr<StmtSeqNode> stmts( parseStmtSeq( STMTS_BLOCK ) );
  143. int pos=toker->pos();
  144. if( toker->curr()!=WEND ) exp( "'Wend'" );
  145. toker->next();
  146. result=d_new WhileNode( expr.release(),stmts.release(),pos );
  147. }
  148. break;
  149. case REPEAT:
  150. {
  151. toker->next();ExprNode *expr=0;
  152. a_ptr<StmtSeqNode> stmts( parseStmtSeq( STMTS_BLOCK ) );
  153. int curr=toker->curr();
  154. int pos=toker->pos();
  155. if( curr!=UNTIL && curr!=FOREVER ) exp( "'Until' or 'Forever'" );
  156. toker->next();if( curr==UNTIL ) expr=parseExpr( false );
  157. result=d_new RepeatNode( stmts.release(),expr,pos );
  158. }
  159. break;
  160. case SELECT:
  161. {
  162. toker->next();ExprNode *expr=parseExpr( false );
  163. a_ptr<SelectNode> selNode( d_new SelectNode( expr ) );
  164. for(;;){
  165. while( isTerm( toker->curr() ) ) toker->next();
  166. if( toker->curr()==CASE ){
  167. toker->next();
  168. a_ptr<ExprSeqNode> exprs( parseExprSeq() );
  169. if( !exprs->size() ) exp( "expression sequence" );
  170. a_ptr<StmtSeqNode> stmts( parseStmtSeq( STMTS_BLOCK ) );
  171. selNode->push_back( d_new CaseNode( exprs.release(),stmts.release() ) );
  172. continue;
  173. }else if( toker->curr()==DEFAULT ){
  174. toker->next();
  175. a_ptr<StmtSeqNode> stmts( parseStmtSeq( STMTS_BLOCK ) );
  176. if( toker->curr()!=ENDSELECT ) exp( "'End Select'" );
  177. selNode->defStmts=stmts.release();
  178. break;
  179. }else if( toker->curr()==ENDSELECT ){
  180. break;
  181. }
  182. exp( "'Case', 'Default' or 'End Select'" );
  183. }
  184. toker->next();
  185. result=selNode.release();
  186. }
  187. break;
  188. case FOR:
  189. {
  190. a_ptr<VarNode> var;
  191. a_ptr<StmtSeqNode> stmts;
  192. toker->next();var=parseVar();
  193. if( toker->curr()!='=' ) exp( "variable assignment" );
  194. if( toker->next()==EACH ){
  195. toker->next();
  196. string ident=parseIdent();
  197. stmts=parseStmtSeq( STMTS_BLOCK );
  198. int pos=toker->pos();
  199. if( toker->curr()!=NEXT ) exp( "'Next'" );
  200. toker->next();
  201. result=d_new ForEachNode( var.release(),ident,stmts.release(),pos );
  202. }else{
  203. a_ptr<ExprNode> from,to,step;
  204. from=parseExpr( false );
  205. if( toker->curr()!=TO ) exp( "'TO'" );
  206. toker->next();to=parseExpr( false );
  207. //step...
  208. if( toker->curr()==STEP ){
  209. toker->next();step=parseExpr( false );
  210. }else step=d_new IntConstNode( 1 );
  211. stmts=parseStmtSeq( STMTS_BLOCK );
  212. int pos=toker->pos();
  213. if( toker->curr()!=NEXT ) exp( "'Next'" );
  214. toker->next();
  215. result=d_new ForNode( var.release(),from.release(),to.release(),step.release(),stmts.release(),pos );
  216. }
  217. }
  218. break;
  219. case EXIT:
  220. {
  221. toker->next();result=d_new ExitNode();
  222. }
  223. break;
  224. case GOTO:
  225. {
  226. toker->next();string t=parseIdent();result=d_new GotoNode( t );
  227. }
  228. break;
  229. case GOSUB:
  230. {
  231. toker->next();string t=parseIdent();result=d_new GosubNode( t );
  232. }
  233. break;
  234. case RETURN:
  235. {
  236. toker->next();result=d_new ReturnNode( parseExpr( true ) );
  237. }
  238. break;
  239. case BBDELETE:
  240. {
  241. if( toker->next()==EACH ){
  242. toker->next();string t=parseIdent();
  243. result=d_new DeleteEachNode( t );
  244. }else{
  245. ExprNode *expr=parseExpr( false );
  246. result=d_new DeleteNode( expr );
  247. }
  248. }
  249. break;
  250. case INSERT:
  251. {
  252. toker->next();
  253. a_ptr<ExprNode> expr1( parseExpr( false ) );
  254. if( toker->curr()!=BEFORE && toker->curr()!=AFTER ) exp( "'Before' or 'After'" );
  255. bool before=toker->curr()==BEFORE;toker->next();
  256. a_ptr<ExprNode> expr2( parseExpr( false ) );
  257. result=d_new InsertNode( expr1.release(),expr2.release(),before );
  258. }
  259. break;
  260. case READ:
  261. do{
  262. toker->next();VarNode *var=parseVar();
  263. StmtNode *stmt=d_new ReadNode( var );
  264. stmt->pos=pos;pos=toker->pos();
  265. stmts->push_back( stmt );
  266. }while( toker->curr()==',' );
  267. break;
  268. case RESTORE:
  269. if( toker->next()==IDENT ){
  270. result=d_new RestoreNode( toker->text() );toker->next();
  271. }else result=d_new RestoreNode( "" );
  272. break;
  273. case DATA:
  274. if( scope!=STMTS_PROG ) ex( "'Data' can only appear in main program" );
  275. do{
  276. toker->next();
  277. ExprNode *expr=parseExpr( false );
  278. datas->push_back( d_new DataDeclNode( expr ) );
  279. }while( toker->curr()==',' );
  280. break;
  281. case TYPE:
  282. if( scope!=STMTS_PROG ) ex( "'Type' can only appear in main program" );
  283. toker->next();structs->push_back( parseStructDecl() );
  284. break;
  285. case BBCONST:
  286. if( scope!=STMTS_PROG ) ex( "'Const' can only appear in main program" );
  287. do{
  288. toker->next();consts->push_back( parseVarDecl( DECL_GLOBAL,true ) );
  289. }while( toker->curr()==',' );
  290. break;
  291. case FUNCTION:
  292. if( scope!=STMTS_PROG ) ex( "'Function' can only appear in main program" );
  293. toker->next();funcs->push_back( parseFuncDecl() );
  294. break;
  295. case DIM:
  296. do{
  297. toker->next();
  298. StmtNode *stmt=parseArrayDecl();
  299. stmt->pos=pos;pos=toker->pos();
  300. stmts->push_back( stmt );
  301. }while( toker->curr()==',' );
  302. break;
  303. case LOCAL:
  304. do{
  305. toker->next();
  306. DeclNode *d=parseVarDecl( DECL_LOCAL,false );
  307. StmtNode *stmt=d_new DeclStmtNode( d );
  308. stmt->pos=pos;pos=toker->pos();
  309. stmts->push_back( stmt );
  310. }while( toker->curr()==',' );
  311. break;
  312. case GLOBAL:
  313. if( scope!=STMTS_PROG ) ex( "'Global' can only appear in main program" );
  314. do{
  315. toker->next();
  316. DeclNode *d=parseVarDecl( DECL_GLOBAL,false );
  317. StmtNode *stmt=d_new DeclStmtNode( d );
  318. stmt->pos=pos;pos=toker->pos();
  319. stmts->push_back( stmt );
  320. }while( toker->curr()==',' );
  321. break;
  322. case '.':
  323. {
  324. toker->next();string t=parseIdent();
  325. result=d_new LabelNode( t,datas->size() );
  326. }
  327. break;
  328. default:
  329. return;
  330. }
  331. if( result ){
  332. result->pos=pos;
  333. stmts->push_back( result );
  334. }
  335. }
  336. }
  337. string Parser::parseTypeTag(){
  338. switch( toker->curr() ){
  339. case '%':toker->next();return "%";
  340. case '#':toker->next();return "#";
  341. case '$':toker->next();return "$";
  342. case '.':toker->next();return parseIdent();
  343. }
  344. return "";
  345. }
  346. VarNode *Parser::parseVar(){
  347. string ident=parseIdent();
  348. string tag=parseTypeTag();
  349. return parseVar( ident,tag );
  350. }
  351. VarNode *Parser::parseVar( const string &ident,const string &tag ){
  352. a_ptr<VarNode> var;
  353. if( toker->curr()=='(' ){
  354. toker->next();
  355. a_ptr<ExprSeqNode> exprs( parseExprSeq() );
  356. if( toker->curr()!=')' ) exp( "')'" );
  357. toker->next();
  358. var=d_new ArrayVarNode( ident,tag,exprs.release() );
  359. }else var=d_new IdentVarNode( ident,tag );
  360. for(;;){
  361. if( toker->curr()=='\\' ){
  362. toker->next();
  363. string ident=parseIdent();
  364. string tag=parseTypeTag();
  365. ExprNode *expr=d_new VarExprNode( var.release() );
  366. var=d_new FieldVarNode( expr,ident,tag );
  367. }else if( toker->curr()=='[' ){
  368. toker->next();
  369. a_ptr<ExprSeqNode> exprs( parseExprSeq() );
  370. if( exprs->exprs.size()!=1 || toker->curr()!=']' ) exp( "']'" );
  371. toker->next();
  372. ExprNode *expr=d_new VarExprNode( var.release() );
  373. var=d_new VectorVarNode( expr,exprs.release() );
  374. }else{
  375. break;
  376. }
  377. }
  378. return var.release();
  379. }
  380. DeclNode *Parser::parseVarDecl( int kind,bool constant ){
  381. int pos=toker->pos();
  382. string ident=parseIdent();
  383. string tag=parseTypeTag();
  384. DeclNode *d;
  385. if( toker->curr()=='[' ){
  386. if( constant ) ex( "Blitz arrays may not be constant" );
  387. toker->next();
  388. a_ptr<ExprSeqNode> exprs( parseExprSeq() );
  389. if( exprs->size()!=1 || toker->curr()!=']' ) exp( "']'" );
  390. toker->next();
  391. d=d_new VectorDeclNode( ident,tag,exprs.release(),kind );
  392. }else{
  393. ExprNode *expr=0;
  394. if( toker->curr()=='=' ){
  395. toker->next();expr=parseExpr( false );
  396. }else if( constant ) ex( "Constants must be initialized" );
  397. d=d_new VarDeclNode( ident,tag,kind,constant,expr );
  398. }
  399. d->pos=pos;d->file=incfile;
  400. return d;
  401. }
  402. DimNode *Parser::parseArrayDecl(){
  403. int pos=toker->pos();
  404. string ident=parseIdent();
  405. string tag=parseTypeTag();
  406. if( toker->curr()!='(' ) exp( "'('" );
  407. toker->next();a_ptr<ExprSeqNode> exprs( parseExprSeq() );
  408. if( toker->curr()!=')' ) exp( "')'" );
  409. if( !exprs->size() ) ex( "can't have a 0 dimensional array" );
  410. toker->next();
  411. DimNode *d=d_new DimNode( ident,tag,exprs.release() );
  412. arrayDecls[ident]=d;
  413. d->pos=pos;
  414. return d;
  415. }
  416. DeclNode *Parser::parseFuncDecl(){
  417. int pos=toker->pos();
  418. string ident=parseIdent();
  419. string tag=parseTypeTag();
  420. if( toker->curr()!='(' ) exp( "'('" );
  421. a_ptr<DeclSeqNode> params( d_new DeclSeqNode() );
  422. if( toker->next()!=')' ){
  423. for(;;){
  424. params->push_back( parseVarDecl( DECL_PARAM,false ) );
  425. if( toker->curr()!=',' ) break;
  426. toker->next();
  427. }
  428. if( toker->curr()!=')' ) exp( "')'" );
  429. }
  430. toker->next();
  431. a_ptr<StmtSeqNode> stmts( parseStmtSeq( STMTS_BLOCK ) );
  432. if( toker->curr()!=ENDFUNCTION ) exp( "'End Function'" );
  433. StmtNode *ret=d_new ReturnNode(0);ret->pos=toker->pos();
  434. stmts->push_back( ret );toker->next();
  435. DeclNode *d=d_new FuncDeclNode( ident,tag,params.release(),stmts.release() );
  436. d->pos=pos;d->file=incfile;
  437. return d;
  438. }
  439. DeclNode *Parser::parseStructDecl(){
  440. int pos=toker->pos();
  441. string ident=parseIdent();
  442. while( toker->curr()=='\n' ) toker->next();
  443. a_ptr<DeclSeqNode> fields( d_new DeclSeqNode() );
  444. while( toker->curr()==FIELD ){
  445. do{
  446. toker->next();
  447. fields->push_back( parseVarDecl( DECL_FIELD,false ) );
  448. }while( toker->curr()==',' );
  449. while( toker->curr()=='\n' ) toker->next();
  450. }
  451. if( toker->curr()!=ENDTYPE ) exp( "'Field' or 'End Type'" );
  452. toker->next();
  453. DeclNode *d=d_new StructDeclNode( ident,fields.release() );
  454. d->pos=pos;d->file=incfile;
  455. return d;
  456. }
  457. IfNode *Parser::parseIf(){
  458. a_ptr<ExprNode> expr;
  459. a_ptr<StmtSeqNode> stmts,elseOpt;
  460. expr=parseExpr( false );
  461. if( toker->curr()==THEN ) toker->next();
  462. bool blkif=isTerm( toker->curr() );
  463. stmts=parseStmtSeq( blkif ? STMTS_BLOCK : STMTS_LINE );
  464. if( toker->curr()==ELSEIF ){
  465. int pos=toker->pos();
  466. toker->next();
  467. IfNode *ifnode=parseIf();
  468. ifnode->pos=pos;
  469. elseOpt=d_new StmtSeqNode( incfile );
  470. elseOpt->push_back( ifnode );
  471. }else if( toker->curr()==ELSE ){
  472. toker->next();
  473. elseOpt=parseStmtSeq( blkif ? STMTS_BLOCK : STMTS_LINE );
  474. }
  475. if( blkif ){
  476. if( toker->curr()!=ENDIF ) exp( "'EndIf'" );
  477. }else if( toker->curr()!='\n' ) exp( "end-of-line" );
  478. return d_new IfNode( expr.release(),stmts.release(),elseOpt.release() );
  479. }
  480. ExprSeqNode *Parser::parseExprSeq(){
  481. a_ptr<ExprSeqNode> exprs( d_new ExprSeqNode() );
  482. bool opt=true;
  483. while( ExprNode *e=parseExpr( opt ) ){
  484. exprs->push_back( e );
  485. if( toker->curr()!=',' ) break;
  486. toker->next();opt=false;
  487. }
  488. return exprs.release();
  489. }
  490. ExprNode *Parser::parseExpr( bool opt ){
  491. if( toker->curr()==NOT ){
  492. toker->next();
  493. ExprNode *expr=parseExpr1( false );
  494. return d_new RelExprNode( '=',expr,d_new IntConstNode( 0 ) );
  495. }
  496. return parseExpr1( opt );
  497. }
  498. ExprNode *Parser::parseExpr1( bool opt ){
  499. a_ptr<ExprNode> lhs( parseExpr2( opt ) );
  500. if( !lhs ) return 0;
  501. for(;;){
  502. int c=toker->curr();
  503. if( c!=AND && c!=OR && c!=XOR ) return lhs.release();
  504. toker->next();ExprNode *rhs=parseExpr2( false );
  505. lhs=d_new BinExprNode( c,lhs.release(),rhs );
  506. }
  507. }
  508. ExprNode *Parser::parseExpr2( bool opt ){
  509. a_ptr<ExprNode> lhs( parseExpr3( opt ) );
  510. if( !lhs ) return 0;
  511. for(;;){
  512. int c=toker->curr();
  513. if( c!='<' && c!='>' && c!='=' && c!=LE && c!=GE && c!=NE ) return lhs.release();
  514. toker->next();ExprNode *rhs=parseExpr3( false );
  515. lhs=d_new RelExprNode( c,lhs.release(),rhs );
  516. }
  517. }
  518. ExprNode *Parser::parseExpr3( bool opt ){
  519. a_ptr<ExprNode> lhs( parseExpr4( opt ) );
  520. if( !lhs ) return 0;
  521. for(;;){
  522. int c=toker->curr();
  523. if( c!='+' && c!='-' ) return lhs.release();
  524. toker->next();ExprNode *rhs=parseExpr4( false );
  525. lhs=d_new ArithExprNode( c,lhs.release(),rhs );
  526. }
  527. }
  528. ExprNode *Parser::parseExpr4( bool opt ){
  529. a_ptr<ExprNode> lhs( parseExpr5( opt ) );
  530. if( !lhs ) return 0;
  531. for(;;){
  532. int c=toker->curr();
  533. if( c!=SHL && c!=SHR && c!=SAR ) return lhs.release();
  534. toker->next();ExprNode *rhs=parseExpr5( false );
  535. lhs=d_new BinExprNode( c,lhs.release(),rhs );
  536. }
  537. }
  538. ExprNode *Parser::parseExpr5( bool opt ){
  539. a_ptr<ExprNode> lhs( parseExpr6( opt ) );
  540. if( !lhs ) return 0;
  541. for(;;){
  542. int c=toker->curr();
  543. if( c!='*' && c!='/' && c!=MOD ) return lhs.release();
  544. toker->next();ExprNode *rhs=parseExpr6( false );
  545. lhs=d_new ArithExprNode( c,lhs.release(),rhs );
  546. }
  547. }
  548. ExprNode *Parser::parseExpr6( bool opt ){
  549. a_ptr<ExprNode> lhs( parseUniExpr( opt ) );
  550. if( !lhs ) return 0;
  551. for(;;){
  552. int c=toker->curr();
  553. if( c!='^' ) return lhs.release();
  554. toker->next();ExprNode *rhs=parseUniExpr( false );
  555. lhs=d_new ArithExprNode( c,lhs.release(),rhs );
  556. }
  557. }
  558. ExprNode *Parser::parseUniExpr( bool opt ){
  559. ExprNode *result=0;
  560. string t;
  561. int c=toker->curr();
  562. switch( c ){
  563. case BBINT:
  564. if( toker->next()=='%' ) toker->next();
  565. result=parseUniExpr( false );
  566. result=d_new CastNode( result,Type::int_type );
  567. break;
  568. case BBFLOAT:
  569. if( toker->next()=='#' ) toker->next();
  570. result=parseUniExpr( false );
  571. result=d_new CastNode( result,Type::float_type );
  572. break;
  573. case BBSTR:
  574. if( toker->next()=='$' ) toker->next();
  575. result=parseUniExpr( false );
  576. result=d_new CastNode( result,Type::string_type );
  577. break;
  578. case OBJECT:
  579. if( toker->next()=='.' ) toker->next();
  580. t=parseIdent();
  581. result=parseUniExpr( false );
  582. result=d_new ObjectCastNode( result,t );
  583. break;
  584. case BBHANDLE:
  585. toker->next();
  586. result=parseUniExpr( false );
  587. result=d_new ObjectHandleNode( result );
  588. break;
  589. case BEFORE:
  590. toker->next();
  591. result=parseUniExpr( false );
  592. result=d_new BeforeNode( result );
  593. break;
  594. case AFTER:
  595. toker->next();
  596. result=parseUniExpr( false );
  597. result=d_new AfterNode( result );
  598. break;
  599. case '+':case '-':case '~':case ABS:case SGN:
  600. toker->next();
  601. result=parseUniExpr( false );
  602. if( c=='~' ){
  603. result=d_new BinExprNode( XOR,result,d_new IntConstNode( -1 ) );
  604. }else{
  605. result=d_new UniExprNode( c,result );
  606. }
  607. break;
  608. default:
  609. result=parsePrimary( opt );
  610. }
  611. return result;
  612. }
  613. ExprNode *Parser::parsePrimary( bool opt ){
  614. a_ptr<ExprNode> expr;
  615. string t,ident,tag;
  616. ExprNode *result=0;
  617. int n,k;
  618. switch( toker->curr() ){
  619. case '(':
  620. toker->next();
  621. expr=parseExpr( false );
  622. if( toker->curr()!=')' ) exp( "')'" );
  623. toker->next();
  624. result=expr.release();
  625. break;
  626. case BBNEW:
  627. toker->next();t=parseIdent();
  628. result=d_new NewNode( t );
  629. break;
  630. case FIRST:
  631. toker->next();t=parseIdent();
  632. result=d_new FirstNode( t );
  633. break;
  634. case LAST:
  635. toker->next();t=parseIdent();
  636. result=d_new LastNode( t );
  637. break;
  638. case BBNULL:
  639. result=d_new NullNode();
  640. toker->next();
  641. break;
  642. case INTCONST:
  643. result=d_new IntConstNode( atoi( toker->text() ) );
  644. toker->next();
  645. break;
  646. case FLOATCONST:
  647. result=d_new FloatConstNode( atof( toker->text() ) );
  648. toker->next();
  649. break;
  650. case STRINGCONST:
  651. t=toker->text();
  652. result=d_new StringConstNode( t.substr( 1,t.size()-2 ) );
  653. toker->next();
  654. break;
  655. case BINCONST:
  656. n=0;t=toker->text();
  657. for( k=1;k<t.size();++k ) n=(n<<1)|(t[k]=='1');
  658. result=d_new IntConstNode( n );
  659. toker->next();
  660. break;
  661. case HEXCONST:
  662. n=0;t=toker->text();
  663. for( k=1;k<t.size();++k ) n=(n<<4)|( isdigit(t[k]) ? t[k]&0xf : (t[k]&7)+9 );
  664. result=d_new IntConstNode( n );
  665. toker->next();
  666. break;
  667. case PI:
  668. result=d_new FloatConstNode( 3.1415926535897932384626433832795f );
  669. toker->next();break;
  670. case BBTRUE:
  671. result=d_new IntConstNode( 1 );
  672. toker->next();break;
  673. case BBFALSE:
  674. result=d_new IntConstNode( 0 );
  675. toker->next();break;
  676. case IDENT:
  677. ident=toker->text();
  678. toker->next();tag=parseTypeTag();
  679. if( toker->curr()=='(' && arrayDecls.find(ident)==arrayDecls.end() ){
  680. //must be a func
  681. toker->next();
  682. a_ptr<ExprSeqNode> exprs( parseExprSeq() );
  683. if( toker->curr()!=')' ) exp( "')'" );
  684. toker->next();
  685. result=d_new CallNode( ident,tag,exprs.release() );
  686. }else{
  687. //must be a var
  688. VarNode *var=parseVar( ident,tag );
  689. result=d_new VarExprNode( var );
  690. }
  691. break;
  692. default:
  693. if( !opt ) exp( "expression" );
  694. }
  695. return result;
  696. }