CMDgram.y 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. %define parse.error custom
  2. %locations
  3. %define api.header.include {"CMDgram.h"}
  4. %{
  5. // bison --defines=cmdgram.h --verbose -o cmdgram.cpp -p CMD CMDgram.y
  6. // Make sure we don't get gram.h twice.
  7. #define _CMDGRAM_H_
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include "console/console.h"
  11. #include "console/torquescript/compiler.h"
  12. #include "console/consoleInternal.h"
  13. #include "core/strings/stringFunctions.h"
  14. #ifndef YYDEBUG
  15. #define YYDEBUG 0
  16. #endif
  17. #define YYSSIZE 350
  18. int outtext(char *fmt, ...);
  19. extern int serrors;
  20. extern Vector<String> lines;
  21. #define nil 0
  22. #undef YY_ARGS
  23. #define YY_ARGS(x) x
  24. int CMDlex();
  25. void CMDerror(const char *, ...);
  26. #ifdef alloca
  27. #undef alloca
  28. #endif
  29. #define alloca dMalloc
  30. template< typename T >
  31. struct Token
  32. {
  33. T value;
  34. U32 lineNumber;
  35. };
  36. %}
  37. %{
  38. /* Reserved Word Definitions */
  39. %}
  40. %token <i> rwDEFINE rwENDDEF rwDECLARE rwDECLARESINGLETON
  41. %token <i> rwBREAK rwELSE rwCONTINUE rwGLOBAL
  42. %token <i> rwIF rwNIL rwRETURN rwWHILE rwDO
  43. %token <i> rwENDIF rwENDWHILE rwENDFOR rwDEFAULT
  44. %token <i> rwFOR rwFOREACH rwFOREACHSTR rwIN rwDATABLOCK rwSWITCH rwCASE rwSWITCHSTR
  45. %token <i> rwCASEOR rwPACKAGE rwNAMESPACE rwCLASS
  46. %token <i> rwASSERT
  47. %token ILLEGAL_TOKEN
  48. %{
  49. /* Constants and Identifier Definitions */
  50. %}
  51. %token <c> CHRCONST
  52. %token <i> INTCONST
  53. %token <s> TTAG
  54. %token <s> VAR
  55. %token <s> IDENT
  56. %token <i> TYPEIDENT
  57. %token <str> DOCBLOCK
  58. %token <str> STRATOM
  59. %token <str> TAGATOM
  60. %token <f> FLTCONST
  61. %{
  62. /* Operator Definitions */
  63. %}
  64. %token <i> '+' '-' '*' '/' '<' '>' '=' '.' '|' '&' '%'
  65. %token <i> '(' ')' ',' ':' ';' '{' '}' '^' '~' '!' '@'
  66. %token <i> opINTNAME opINTNAMER
  67. %token <i> opMINUSMINUS opPLUSPLUS
  68. %token <i> STMT_SEP
  69. %token <i> opSHL opSHR opPLASN opMIASN opMLASN opDVASN opMODASN opANDASN
  70. %token <i> opXORASN opORASN opSLASN opSRASN opCAT
  71. %token <i> opEQ opNE opGE opLE opAND opOR opSTREQ
  72. %token <i> opCOLONCOLON
  73. %union {
  74. Token< char > c;
  75. Token< int > i;
  76. Token< const char* > s;
  77. Token< char* > str;
  78. Token< double > f;
  79. StmtNode* stmt;
  80. ExprNode* expr;
  81. SlotAssignNode* slist;
  82. VarNode* var;
  83. SlotDecl slot;
  84. InternalSlotDecl intslot;
  85. ObjectBlockDecl odcl;
  86. ObjectDeclNode* od;
  87. AssignDecl asn;
  88. IfStmtNode* ifnode;
  89. }
  90. %type <s> parent_block
  91. %type <ifnode> case_block
  92. %type <stmt> switch_stmt
  93. %type <stmt> decl
  94. %type <stmt> decl_list
  95. %type <stmt> package_decl
  96. %type <stmt> fn_decl_stmt
  97. %type <stmt> fn_decl_list
  98. %type <stmt> statement_list
  99. %type <stmt> stmt
  100. %type <expr> expr_list
  101. %type <expr> expr_list_decl
  102. %type <expr> aidx_expr
  103. %type <expr> funcall_expr
  104. %type <expr> assert_expr
  105. %type <expr> object_name
  106. %type <expr> object_args
  107. %type <expr> stmt_expr
  108. %type <expr> case_expr
  109. %type <expr> class_name_expr
  110. %type <stmt> if_stmt
  111. %type <stmt> while_stmt
  112. %type <stmt> for_stmt
  113. %type <stmt> foreach_stmt
  114. %type <stmt> stmt_block
  115. %type <stmt> datablock_decl
  116. %type <od> object_decl
  117. %type <od> object_decl_list
  118. %type <odcl> object_declare_block
  119. %type <expr> expr
  120. %type <slist> slot_assign_list_opt
  121. %type <slist> slot_assign_list
  122. %type <slist> slot_assign
  123. %type <slot> slot_acc
  124. %type <intslot> intslot_acc
  125. %type <stmt> expression_stmt
  126. %type <var> var_list
  127. %type <var> var_list_decl
  128. %type <asn> assign_op_struct
  129. %left '['
  130. %right opMODASN opANDASN opXORASN opPLASN opMIASN opMLASN opDVASN opMDASN opNDASN opNTASN opORASN opSLASN opSRASN '='
  131. %left '?' ':'
  132. %left opOR
  133. %left opAND
  134. %left '|'
  135. %left '^'
  136. %left '&'
  137. %left opEQ opNE
  138. %left '<' opLE '>' opGE
  139. %left '@' opCAT opSTREQ opSTRNE
  140. %left opSHL opSHR
  141. %left '+' '-'
  142. %left '*' '/' '%'
  143. %right '!' '~' opPLUSPLUS opMINUSMINUS UNARY
  144. %left '.'
  145. %left opINTNAME opINTNAMER
  146. %%
  147. start
  148. : decl_list
  149. { }
  150. ;
  151. decl_list
  152. :
  153. { $$ = nil; }
  154. | decl_list decl
  155. { if(!Script::gStatementList) { Script::gStatementList = $2; } else { Script::gStatementList->append($2); } }
  156. ;
  157. decl
  158. : stmt
  159. { $$ = $1; }
  160. | fn_decl_stmt
  161. { $$ = $1; }
  162. | package_decl
  163. { $$ = $1; }
  164. ;
  165. package_decl
  166. : rwPACKAGE IDENT '{' fn_decl_list '}' ';'
  167. { $$ = $4; for(StmtNode *walk = ($4);walk;walk = walk->getNext() ) walk->setPackage($2.value); }
  168. ;
  169. fn_decl_list
  170. : fn_decl_stmt
  171. { $$ = $1; }
  172. | fn_decl_list fn_decl_stmt
  173. { $$ = $1; ($1)->append($2); }
  174. ;
  175. statement_list
  176. :
  177. { $$ = nil; }
  178. | statement_list stmt
  179. { if(!$1) { $$ = $2; } else { ($1)->append($2); $$ = $1; } }
  180. ;
  181. stmt
  182. : if_stmt
  183. | while_stmt
  184. | for_stmt
  185. | foreach_stmt
  186. | datablock_decl
  187. | switch_stmt
  188. | rwBREAK ';'
  189. { $$ = BreakStmtNode::alloc( $1.lineNumber ); }
  190. | rwCONTINUE ';'
  191. { $$ = ContinueStmtNode::alloc( $1.lineNumber ); }
  192. | rwRETURN ';'
  193. { $$ = ReturnStmtNode::alloc( $1.lineNumber, NULL ); }
  194. | rwRETURN expr ';'
  195. { $$ = ReturnStmtNode::alloc( $1.lineNumber, $2 ); }
  196. | expression_stmt ';'
  197. { $$ = $1; }
  198. | TTAG '=' expr ';'
  199. { $$ = TTagSetStmtNode::alloc( $1.lineNumber, $1.value, $3, NULL ); }
  200. | TTAG '=' expr ',' expr ';'
  201. { $$ = TTagSetStmtNode::alloc( $1.lineNumber, $1.value, $3, $5 ); }
  202. | DOCBLOCK
  203. { $$ = StrConstNode::alloc( $1.lineNumber, $1.value, false, true ); }
  204. ;
  205. fn_decl_stmt
  206. : rwDEFINE IDENT '(' var_list_decl ')' '{' statement_list '}'
  207. { $$ = FunctionDeclStmtNode::alloc( $1.lineNumber, $2.value, NULL, $4, $7 ); }
  208. | rwDEFINE IDENT opCOLONCOLON IDENT '(' var_list_decl ')' '{' statement_list '}'
  209. { $$ = FunctionDeclStmtNode::alloc( $1.lineNumber, $4.value, $2.value, $6, $9 ); }
  210. ;
  211. var_list_decl
  212. :
  213. { $$ = NULL; }
  214. | var_list
  215. { $$ = $1; }
  216. ;
  217. var_list
  218. : VAR
  219. { $$ = VarNode::alloc( $1.lineNumber, $1.value, NULL ); }
  220. | var_list ',' VAR
  221. { $$ = $1; ((StmtNode*)($1))->append((StmtNode*)VarNode::alloc( $3.lineNumber, $3.value, NULL ) ); }
  222. ;
  223. datablock_decl
  224. : rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';'
  225. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, NULL, $5.value, $8, NULL, true, false, false); }
  226. ;
  227. object_decl
  228. : rwDECLARE class_name_expr '(' object_name parent_block object_args ')' '{' object_declare_block '}'
  229. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, $6, $5.value, $9.slots, $9.decls, false, false, false); }
  230. | rwDECLARE class_name_expr '(' object_name parent_block object_args ')'
  231. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, $6, $5.value, NULL, NULL, false, false, false); }
  232. | rwDECLARE class_name_expr '(' '[' object_name ']' parent_block object_args ')' '{' object_declare_block '}'
  233. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $5, $8, $7.value, $11.slots, $11.decls, false, true, false); }
  234. | rwDECLARE class_name_expr '(' '[' object_name ']' parent_block object_args ')'
  235. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $5, $8, $7.value, NULL, NULL, false, true, false); }
  236. | rwDECLARESINGLETON class_name_expr '(' object_name parent_block object_args ')' '{' object_declare_block '}'
  237. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, $6, $5.value, $9.slots, $9.decls, false, false, true); }
  238. | rwDECLARESINGLETON class_name_expr '(' object_name parent_block object_args ')'
  239. { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, $6, $5.value, NULL, NULL, false, false, true); }
  240. ;
  241. parent_block
  242. :
  243. { $$.value = NULL; }
  244. | ':' IDENT
  245. { $$ = $2; }
  246. ;
  247. object_name
  248. :
  249. { $$ = StrConstNode::alloc( CodeBlock::smCurrentParser->getCurrentLine(), "", false); }
  250. | expr
  251. { $$ = $1; }
  252. ;
  253. object_args
  254. :
  255. { $$ = NULL; }
  256. | ',' expr_list
  257. { $$ = $2; }
  258. ;
  259. object_declare_block
  260. :
  261. { $$.slots = NULL; $$.decls = NULL; }
  262. | slot_assign_list
  263. { $$.slots = $1; $$.decls = NULL; }
  264. | object_decl_list
  265. { $$.slots = NULL; $$.decls = $1; }
  266. | slot_assign_list object_decl_list
  267. { $$.slots = $1; $$.decls = $2; }
  268. ;
  269. object_decl_list
  270. : object_decl ';'
  271. { $$ = $1; }
  272. | object_decl_list object_decl ';'
  273. { $1->append($2); $$ = $1; }
  274. ;
  275. stmt_block
  276. : '{' statement_list '}'
  277. { $$ = $2; }
  278. | stmt
  279. { $$ = $1; }
  280. ;
  281. switch_stmt
  282. : rwSWITCH '(' expr ')' '{' case_block '}'
  283. { $$ = $6; $6->propagateSwitchExpr($3, false); }
  284. | rwSWITCHSTR '(' expr ')' '{' case_block '}'
  285. { $$ = $6; $6->propagateSwitchExpr($3, true); }
  286. ;
  287. case_block
  288. : rwCASE case_expr ':' statement_list
  289. { $$ = IfStmtNode::alloc( $1.lineNumber, $2, $4, NULL, false); }
  290. | rwCASE case_expr ':' statement_list rwDEFAULT ':' statement_list
  291. { $$ = IfStmtNode::alloc( $1.lineNumber, $2, $4, $7, false); }
  292. | rwCASE case_expr ':' statement_list case_block
  293. { $$ = IfStmtNode::alloc( $1.lineNumber, $2, $4, $5, true); }
  294. ;
  295. case_expr
  296. : expr
  297. { $$ = $1;}
  298. | case_expr rwCASEOR expr
  299. { ($1)->append($3); $$=$1; }
  300. ;
  301. if_stmt
  302. : rwIF '(' expr ')' stmt_block
  303. { $$ = IfStmtNode::alloc($1.lineNumber, $3, $5, NULL, false); }
  304. | rwIF '(' expr ')' stmt_block rwELSE stmt_block
  305. { $$ = IfStmtNode::alloc($1.lineNumber, $3, $5, $7, false); }
  306. ;
  307. while_stmt
  308. : rwWHILE '(' expr ')' stmt_block
  309. { $$ = LoopStmtNode::alloc($1.lineNumber, nil, $3, nil, $5, false); }
  310. | rwDO stmt_block rwWHILE '(' expr ')'
  311. { $$ = LoopStmtNode::alloc($3.lineNumber, nil, $5, nil, $2, true); }
  312. ;
  313. for_stmt
  314. : rwFOR '(' expr ';' expr ';' expr ')' stmt_block
  315. { $$ = LoopStmtNode::alloc($1.lineNumber, $3, $5, $7, $9, false); }
  316. | rwFOR '(' expr ';' expr ';' ')' stmt_block
  317. { $$ = LoopStmtNode::alloc($1.lineNumber, $3, $5, NULL, $8, false); }
  318. | rwFOR '(' expr ';' ';' expr ')' stmt_block
  319. { $$ = LoopStmtNode::alloc($1.lineNumber, $3, NULL, $6, $8, false); }
  320. | rwFOR '(' expr ';' ';' ')' stmt_block
  321. { $$ = LoopStmtNode::alloc($1.lineNumber, $3, NULL, NULL, $7, false); }
  322. | rwFOR '(' ';' expr ';' expr ')' stmt_block
  323. { $$ = LoopStmtNode::alloc($1.lineNumber, NULL, $4, $6, $8, false); }
  324. | rwFOR '(' ';' expr ';' ')' stmt_block
  325. { $$ = LoopStmtNode::alloc($1.lineNumber, NULL, $4, NULL, $7, false); }
  326. | rwFOR '(' ';' ';' expr ')' stmt_block
  327. { $$ = LoopStmtNode::alloc($1.lineNumber, NULL, NULL, $5, $7, false); }
  328. | rwFOR '(' ';' ';' ')' stmt_block
  329. { $$ = LoopStmtNode::alloc($1.lineNumber, NULL, NULL, NULL, $6, false); }
  330. ;
  331. foreach_stmt
  332. : rwFOREACH '(' VAR rwIN expr ')' stmt_block
  333. { $$ = IterStmtNode::alloc( $1.lineNumber, $3.value, $5, $7, false ); }
  334. | rwFOREACHSTR '(' VAR rwIN expr ')' stmt_block
  335. { $$ = IterStmtNode::alloc( $1.lineNumber, $3.value, $5, $7, true ); }
  336. ;
  337. expression_stmt
  338. : stmt_expr
  339. { $$ = $1; }
  340. ;
  341. expr
  342. : stmt_expr
  343. { $$ = $1; }
  344. | '(' expr ')'
  345. { $$ = $2; }
  346. | expr '^' expr
  347. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  348. | expr '%' expr
  349. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  350. | expr '&' expr
  351. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  352. | expr '|' expr
  353. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  354. | expr '+' expr
  355. { $$ = FloatBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  356. | expr '-' expr
  357. { $$ = FloatBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  358. | expr '*' expr
  359. { $$ = FloatBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  360. | expr '/' expr
  361. { $$ = FloatBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  362. | '-' expr %prec UNARY
  363. { $$ = FloatUnaryExprNode::alloc( $1.lineNumber, $1.value, $2); }
  364. | '*' expr %prec UNARY
  365. { $$ = TTagDerefNode::alloc( $1.lineNumber, $2 ); }
  366. | TTAG
  367. { $$ = TTagExprNode::alloc( $1.lineNumber, $1.value ); }
  368. | expr '?' expr ':' expr
  369. { $$ = ConditionalExprNode::alloc( $1->dbgLineNumber, $1, $3, $5); }
  370. | expr '<' expr
  371. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  372. | expr '>' expr
  373. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  374. | expr opGE expr
  375. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  376. | expr opLE expr
  377. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  378. | expr opEQ expr
  379. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  380. | expr opNE expr
  381. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  382. | expr opOR expr
  383. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  384. | expr opSHL expr
  385. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  386. | expr opSHR expr
  387. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  388. | expr opAND expr
  389. { $$ = IntBinaryExprNode::alloc( $1->dbgLineNumber, $2.value, $1, $3); }
  390. | expr opSTREQ expr
  391. { $$ = StreqExprNode::alloc( $1->dbgLineNumber, $1, $3, true); }
  392. | expr opSTRNE expr
  393. { $$ = StreqExprNode::alloc( $1->dbgLineNumber, $1, $3, false); }
  394. | expr '@' expr
  395. { $$ = StrcatExprNode::alloc( $1->dbgLineNumber, $1, $3, $2.value); }
  396. | '!' expr
  397. { $$ = IntUnaryExprNode::alloc($1.lineNumber, $1.value, $2); }
  398. | '~' expr
  399. { $$ = IntUnaryExprNode::alloc($1.lineNumber, $1.value, $2); }
  400. | TAGATOM
  401. { $$ = StrConstNode::alloc( $1.lineNumber, $1.value, true); }
  402. | FLTCONST
  403. { $$ = FloatNode::alloc( $1.lineNumber, $1.value ); }
  404. | INTCONST
  405. { $$ = IntNode::alloc( $1.lineNumber, $1.value ); }
  406. | rwBREAK
  407. { $$ = ConstantNode::alloc( $1.lineNumber, StringTable->insert("break")); }
  408. | slot_acc
  409. { $$ = SlotAccessNode::alloc( $1.lineNumber, $1.object, $1.array, $1.slotName ); }
  410. | intslot_acc
  411. { $$ = InternalSlotAccessNode::alloc( $1.lineNumber, $1.object, $1.slotExpr, $1.recurse); }
  412. | IDENT
  413. { $$ = ConstantNode::alloc( $1.lineNumber, $1.value ); }
  414. | STRATOM
  415. { $$ = StrConstNode::alloc( $1.lineNumber, $1.value, false); }
  416. | VAR
  417. { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, NULL); }
  418. | VAR '[' aidx_expr ']'
  419. { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); }
  420. ;
  421. /*
  422. | rwDEFINE '(' var_list_decl ')' '{' statement_list '}'
  423. {
  424. const U32 bufLen = 64;
  425. UTF8 buffer[bufLen];
  426. dSprintf(buffer, bufLen, "__anonymous_function%d", gAnonFunctionID++);
  427. StringTableEntry fName = StringTable->insert(buffer);
  428. StmtNode *fndef = FunctionDeclStmtNode::alloc($1.lineNumber, fName, NULL, $3, $6);
  429. if(!gAnonFunctionList)
  430. gAnonFunctionList = fndef;
  431. else
  432. gAnonFunctionList->append(fndef);
  433. $$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fName, false );
  434. }
  435. */
  436. slot_acc
  437. : expr '.' IDENT
  438. { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotName = $3.value; $$.array = NULL; }
  439. | expr '.' IDENT '[' aidx_expr ']'
  440. { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotName = $3.value; $$.array = $5; }
  441. ;
  442. intslot_acc
  443. : expr opINTNAME class_name_expr
  444. { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotExpr = $3; $$.recurse = false; }
  445. | expr opINTNAMER class_name_expr
  446. { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotExpr = $3; $$.recurse = true; }
  447. ;
  448. class_name_expr
  449. : IDENT
  450. { $$ = ConstantNode::alloc( $1.lineNumber, $1.value ); }
  451. | '(' expr ')'
  452. { $$ = $2; }
  453. ;
  454. assign_op_struct
  455. : opPLUSPLUS
  456. { $$.lineNumber = $1.lineNumber; $$.token = opPLUSPLUS; $$.expr = FloatNode::alloc( $1.lineNumber, 1 ); }
  457. | opMINUSMINUS
  458. { $$.lineNumber = $1.lineNumber; $$.token = opMINUSMINUS; $$.expr = FloatNode::alloc( $1.lineNumber, 1 ); }
  459. | opPLASN expr
  460. { $$.lineNumber = $1.lineNumber; $$.token = '+'; $$.expr = $2; }
  461. | opMIASN expr
  462. { $$.lineNumber = $1.lineNumber; $$.token = '-'; $$.expr = $2; }
  463. | opMLASN expr
  464. { $$.lineNumber = $1.lineNumber; $$.token = '*'; $$.expr = $2; }
  465. | opDVASN expr
  466. { $$.lineNumber = $1.lineNumber; $$.token = '/'; $$.expr = $2; }
  467. | opMODASN expr
  468. { $$.lineNumber = $1.lineNumber; $$.token = '%'; $$.expr = $2; }
  469. | opANDASN expr
  470. { $$.lineNumber = $1.lineNumber; $$.token = '&'; $$.expr = $2; }
  471. | opXORASN expr
  472. { $$.lineNumber = $1.lineNumber; $$.token = '^'; $$.expr = $2; }
  473. | opORASN expr
  474. { $$.lineNumber = $1.lineNumber; $$.token = '|'; $$.expr = $2; }
  475. | opSLASN expr
  476. { $$.lineNumber = $1.lineNumber; $$.token = opSHL; $$.expr = $2; }
  477. | opSRASN expr
  478. { $$.lineNumber = $1.lineNumber; $$.token = opSHR; $$.expr = $2; }
  479. ;
  480. stmt_expr
  481. : funcall_expr
  482. { $$ = $1; }
  483. | assert_expr
  484. { $$ = $1; }
  485. | object_decl
  486. { $$ = $1; }
  487. | VAR '=' expr
  488. { $$ = AssignExprNode::alloc( $1.lineNumber, $1.value, NULL, $3); }
  489. | VAR '[' aidx_expr ']' '=' expr
  490. { $$ = AssignExprNode::alloc( $1.lineNumber, $1.value, $3, $6); }
  491. | VAR assign_op_struct
  492. { $$ = AssignOpExprNode::alloc( $1.lineNumber, $1.value, NULL, $2.expr, $2.token); }
  493. | VAR '[' aidx_expr ']' assign_op_struct
  494. { $$ = AssignOpExprNode::alloc( $1.lineNumber, $1.value, $3, $5.expr, $5.token); }
  495. | slot_acc assign_op_struct
  496. { $$ = SlotAssignOpNode::alloc( $1.lineNumber, $1.object, $1.slotName, $1.array, $2.token, $2.expr); }
  497. | slot_acc '=' expr
  498. { $$ = SlotAssignNode::alloc( $1.lineNumber, $1.object, $1.array, $1.slotName, $3); }
  499. | slot_acc '=' '{' expr_list '}'
  500. { $$ = SlotAssignNode::alloc( $1.lineNumber, $1.object, $1.array, $1.slotName, $4); }
  501. ;
  502. funcall_expr
  503. : IDENT '(' expr_list_decl ')'
  504. { $$ = FuncCallExprNode::alloc( $1.lineNumber, $1.value, NULL, $3, false); }
  505. | IDENT opCOLONCOLON IDENT '(' expr_list_decl ')'
  506. { $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); }
  507. | expr '.' IDENT '(' expr_list_decl ')'
  508. { $1->append($5); $$ = FuncCallExprNode::alloc( $1->dbgLineNumber, $3.value, NULL, $1, true); }
  509. ;
  510. /*
  511. | expr '(' expr_list_decl ')'
  512. { $$ = FuncPointerCallExprNode::alloc( $1->dbgLineNumber, $1, $3); }
  513. ;
  514. */
  515. assert_expr
  516. : rwASSERT '(' expr ')'
  517. { $$ = AssertCallExprNode::alloc( $1.lineNumber, $3, NULL ); }
  518. | rwASSERT '(' expr ',' STRATOM ')'
  519. { $$ = AssertCallExprNode::alloc( $1.lineNumber, $3, $5.value ); }
  520. ;
  521. expr_list_decl
  522. :
  523. { $$ = NULL; }
  524. | expr_list
  525. { $$ = $1; }
  526. ;
  527. expr_list
  528. : expr
  529. { $$ = $1; }
  530. | expr_list ',' expr
  531. { ($1)->append($3); $$ = $1; }
  532. ;
  533. slot_assign_list_opt
  534. :
  535. { $$ = NULL; }
  536. | slot_assign_list
  537. { $$ = $1; }
  538. ;
  539. slot_assign_list
  540. : slot_assign
  541. { $$ = $1; }
  542. | slot_assign_list slot_assign
  543. { $1->append($2); $$ = $1; }
  544. ;
  545. slot_assign
  546. : IDENT '=' expr ';'
  547. { $$ = SlotAssignNode::alloc( $1.lineNumber, NULL, NULL, $1.value, $3); }
  548. | TYPEIDENT IDENT '=' expr ';'
  549. { $$ = SlotAssignNode::alloc( $1.lineNumber, NULL, NULL, $2.value, $4, $1.value); }
  550. | rwDATABLOCK '=' expr ';'
  551. { $$ = SlotAssignNode::alloc( $1.lineNumber, NULL, NULL, StringTable->insert("datablock"), $3); }
  552. | IDENT '[' aidx_expr ']' '=' expr ';'
  553. { $$ = SlotAssignNode::alloc( $1.lineNumber, NULL, $3, $1.value, $6); }
  554. | TYPEIDENT IDENT '[' aidx_expr ']' '=' expr ';'
  555. { $$ = SlotAssignNode::alloc( $1.lineNumber, NULL, $4, $2.value, $7, $1.value); }
  556. ;
  557. aidx_expr
  558. : expr
  559. { $$ = $1; }
  560. | aidx_expr ',' expr
  561. { $$ = CommaCatExprNode::alloc( $1->dbgLineNumber, $1, $3); }
  562. ;
  563. %%
  564. int
  565. yyreport_syntax_error (const yypcontext_t *ctx)
  566. {
  567. int ret = 0;
  568. String output;
  569. const YYLTYPE *loc = yypcontext_location (ctx);
  570. output += "syntax error: ";
  571. yysymbol_kind_t nxt = yypcontext_token(ctx);
  572. if (nxt != YYSYMBOL_YYEMPTY)
  573. output += String::ToString("unexpected: %s at column: %d", yysymbol_name(nxt), loc->first_column);
  574. enum { TOKENMAX = 10 };
  575. yysymbol_kind_t expected[TOKENMAX];
  576. int exp = yypcontext_expected_tokens(ctx, expected, TOKENMAX);
  577. if (exp < 0)
  578. ret = exp;
  579. else
  580. {
  581. for (int i = 0; i < exp; ++i)
  582. output += String::ToString("%s %s", i == 0 ? ": expected" : "or", yysymbol_name(expected[i]));
  583. }
  584. if (lines.size() > 0)
  585. {
  586. output += "\n";
  587. for (int i = 0; i < lines.size(); i++)
  588. {
  589. int line = lines.size() - i;
  590. output += String::ToString("%5d | ", loc->first_line - (line-1)) + lines[i] + "\n";
  591. }
  592. output += String::ToString("%5s | %*s", "", loc->first_column, "^");
  593. }
  594. yyerror("%s", output.c_str());
  595. return ret;
  596. }