PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/ScriptEngine/javascript.y

https://github.com/pruano/Byakhee
Happy | 674 lines | 521 code | 153 blank | 0 comment | 0 complexity | ac9b821f645773fc7bc25c66617a22df MD5 | raw file
Possible License(s): GPL-2.0
  1. %token FUNCTION IF ELSE FOR WHILE RETURN BREAK CONTINUE NEW STRING VAR OCTAL_DIGIT FLOAT_DIGIT HEX_DIGIT DECIMAL_DIGIT IDENTIFIER ASSIGN ADDASSIGN SUBASSIGN MULASSIGN DIVASSIGN MODASSIGN ANDASSIGN ORASSIGN XORASSIGN SHLASSIGN SSHRASSIGN LOGOR LOGAND BITOR BITAND BITXOR ISEQUALS ISNOTEQUALS ISLTHAN ISGTHAN ISLTHANEQUALS ISGTHANEQUALS SHL SSHR ADD MUL DIV MOD INCREMENT DECREMENT
  2. %start script
  3. %{
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "ParseTree.h"
  7. extern int g_nLineNumber;
  8. /* global script data pointers ************************************************************/
  9. LPNODE g_pScriptNode = NULL; //pointer to script's root node
  10. LPFUNCTION g_pFunctionList = NULL; //pointer to script's function list
  11. LPNODE g_pNodeList = NULL; //pointer to linear script node list
  12. /* item creation functions ****************************************************************/
  13. void yyerror( char *s );
  14. LPNODE NewNode( NODETYPE type, LPNODE pLeft, LPNODE pRight, LPNODE pOther1 = NULL, LPNODE pOther2 = NULL )
  15. {
  16. if( type == ntINVALID ) return NULL;
  17. LPNODE pNew = new NODE;
  18. pNew->NodeType = type;
  19. pNew->Left.pNode = pLeft;
  20. pNew->Right.pNode = pRight;
  21. pNew->Other1.pNode = pOther1;
  22. pNew->Other2.pNode = pOther2;
  23. pNew->fLeaf = FALSE;
  24. pNew->nLineNumber = g_nLineNumber;
  25. //link it in to the global list
  26. pNew->next = g_pNodeList;
  27. g_pNodeList = pNew;
  28. return pNew;
  29. }
  30. LPNODE NewLeaf( NODETYPE type, int nValue )
  31. {
  32. if( type == ntINVALID ) return NULL;
  33. LPNODE pNew = new NODE;
  34. pNew->NodeType = type;
  35. pNew->Left.nValue = nValue;
  36. pNew->Right.nValue = 0;
  37. pNew->Other1.nValue = 0;
  38. pNew->Other2.nValue = 0;
  39. pNew->fLeaf = TRUE;
  40. pNew->fString = FALSE;
  41. pNew->nLineNumber = g_nLineNumber;
  42. //link it in to the global list
  43. pNew->next = g_pNodeList;
  44. g_pNodeList = pNew;
  45. return pNew;
  46. }
  47. LPNODE NewLeaf( NODETYPE type, double dValue )
  48. {
  49. if( type == ntINVALID ) return NULL;
  50. LPNODE pNew = new NODE;
  51. pNew->NodeType = type;
  52. pNew->Left.dValue = dValue;
  53. pNew->Right.dValue = 0;
  54. pNew->Other1.dValue = 0;
  55. pNew->Other2.dValue = 0;
  56. pNew->fLeaf = TRUE;
  57. pNew->fString = FALSE;
  58. pNew->nLineNumber = g_nLineNumber;
  59. //link it in to the global list
  60. pNew->next = g_pNodeList;
  61. g_pNodeList = pNew;
  62. return pNew;
  63. }
  64. LPNODE NewLeaf( NODETYPE type, char* pszString = NULL )
  65. {
  66. if( type == ntINVALID ) return NULL;
  67. LPNODE pNew = new NODE;
  68. pNew->NodeType = type;
  69. pNew->Left.strToken = pszString == NULL ? NULL : strdup(pszString);
  70. pNew->Right.strToken = NULL;
  71. pNew->Other1.strToken = NULL;
  72. pNew->Other2.strToken = NULL;
  73. pNew->fLeaf = TRUE;
  74. pNew->fString = TRUE;
  75. pNew->nLineNumber = g_nLineNumber;
  76. //link it in to the global list
  77. pNew->next = g_pNodeList;
  78. g_pNodeList = pNew;
  79. return pNew;
  80. }
  81. LPARGUMENT NewFormalArgument( LPARGUMENT pArguments, LPNODE pNodeName )
  82. {
  83. if( pArguments )
  84. {
  85. LPARGUMENT pList = pArguments;
  86. while( pList )
  87. {
  88. if( strcmp( pList->pNode->Left.strToken, pNodeName->Left.strToken ) == 0 )
  89. {
  90. yyerror( "Argument already exists!" );
  91. return NULL;
  92. }
  93. pList = pList->next;
  94. }
  95. }
  96. //allocate the argument structure and fill it in
  97. LPARGUMENT pNew = new ARGUMENT;
  98. pNew->pNode = pNodeName;
  99. pNew->next = NULL;
  100. //link it to the list (at the end - the arguments must be in order)
  101. if( pArguments == NULL )
  102. //this is the first item
  103. return pNew;
  104. else
  105. {
  106. //a list exists already - add this one at the end
  107. LPARGUMENT pEndOfList = pArguments;
  108. while( pEndOfList->next != NULL ) pEndOfList = pEndOfList->next;
  109. pEndOfList->next = pNew;
  110. return pArguments;
  111. }
  112. }
  113. LPNODE NewFunction( LPNODE pFunctionBodyNode, LPARGUMENT pArguments, LPNODE pFunctionNameLeaf )
  114. {
  115. if( pArguments )
  116. {
  117. LPFUNCTION pList = g_pFunctionList;
  118. while( pList )
  119. {
  120. if( strcmp( pList->pFunctionNameLeaf->Left.strToken, pFunctionNameLeaf->Left.strToken ) == 0 )
  121. {
  122. yyerror( "Function already exists" );
  123. return NULL;
  124. }
  125. pList = pList->next;
  126. }
  127. }
  128. //allocate the function stucture and fill it in
  129. LPFUNCTION pNew = new FUNCTION;
  130. pNew->pFunctionNameLeaf = pFunctionNameLeaf;
  131. pNew->pFunctionBodyNode = pFunctionBodyNode;
  132. pNew->pArguments = pArguments;
  133. //link it to the list (at the start - the function order does not matter)
  134. pNew->next = g_pFunctionList;
  135. g_pFunctionList = pNew;
  136. return pFunctionNameLeaf;
  137. }
  138. LPARGUMENT NewActualArgument( LPARGUMENT pArguments, LPNODE pNodeValue )
  139. {
  140. //allocate the argument structure and fill it in
  141. LPARGUMENT pNew = new ARGUMENT;
  142. pNew->pNode = pNodeValue;
  143. pNew->next = NULL;
  144. //link it to the list (at the end - the arguments must be in order)
  145. if( pArguments == NULL )
  146. //this is the first item
  147. return pNew;
  148. else
  149. {
  150. //a list exists already - add this one at the end
  151. LPARGUMENT pEndOfList = pArguments;
  152. while( pEndOfList->next != NULL ) pEndOfList = pEndOfList->next;
  153. pEndOfList->next = pNew;
  154. return pArguments;
  155. }
  156. }
  157. int DecodeOctal( char* pszOctal )
  158. {
  159. //it's in the C form of 0NNNNN
  160. int n = 0;
  161. sscanf( pszOctal+1, "%o", &n );
  162. return n;
  163. }
  164. double DecodeFloat( char* pszFloat )
  165. {
  166. return atof( pszFloat );
  167. }
  168. int DecodeHex( char* pszHex )
  169. {
  170. //it's in the C form of 0xNNNNN
  171. int n = 0;
  172. sscanf( pszHex+2, "%x", &n );
  173. return n;
  174. }
  175. int DecodeDecimal( char* pszDecimal )
  176. {
  177. return atoi( pszDecimal );
  178. }
  179. /* tree destruction function **************************************************************/
  180. void DeleteArguments( LPARGUMENT pArg )
  181. {
  182. LPARGUMENT pTemp;
  183. while( pArg )
  184. {
  185. pTemp = pArg;
  186. pArg = pArg->next;
  187. delete pTemp;
  188. }
  189. }
  190. LPNODE DeleteNode( LPNODE pNode )
  191. {
  192. if( pNode == NULL ) return NULL;
  193. LPNODE pReturn = pNode->next;
  194. //delete this node/leaf
  195. if( pNode->fLeaf == TRUE )
  196. {
  197. if( pNode->fString == TRUE )
  198. {
  199. //delete the strings
  200. delete[] pNode->Left.strToken;
  201. delete[] pNode->Right.strToken;
  202. delete[] pNode->Other1.strToken;
  203. delete[] pNode->Other2.strToken;
  204. }
  205. }
  206. else
  207. {
  208. //delete child nodes
  209. switch( pNode->NodeType )
  210. {
  211. case ntOBJECTMETHODCALL:
  212. DeleteArguments( (LPARGUMENT)pNode->Other1.pNode );
  213. break;
  214. case ntFUNCTIONCALL:
  215. case ntCONSTRUCTOR:
  216. DeleteArguments( (LPARGUMENT)pNode->Right.pNode );
  217. break;
  218. }
  219. }
  220. //delete this node
  221. delete pNode;
  222. return pReturn;
  223. }
  224. void FreeParseInformation( LPNODE pNodeList, LPFUNCTION pFunctionList )
  225. {
  226. //delete the parse tree
  227. while( pNodeList ) pNodeList = DeleteNode( pNodeList );
  228. LPFUNCTION pTemp;
  229. while( pFunctionList )
  230. {
  231. DeleteArguments( pFunctionList->pArguments );
  232. pTemp = pFunctionList;
  233. pFunctionList = pFunctionList->next;
  234. delete pTemp;
  235. }
  236. }
  237. %}
  238. %union {
  239. LPNODE pNode;
  240. LPARGUMENT pFormalArgs;
  241. LPARGUMENT pActualArgs;
  242. NODETYPE NodeType;
  243. }
  244. %type <pNode> script
  245. %type <pNode> stmtsfuncs
  246. %type <pNode> function functionBody vars varDeclarations varDeclaration
  247. %type <pNode> statementBlock statements statement
  248. %type <pNode> ifStatement forStatement whileStatement returnStatement breakStatement continueStatement
  249. %type <pNode> expression optionalExpression assign_expression conditional_expression or_expression and_expression bitor_expression xor_expression bitand_expression equality_expression relational_expression shift_expression add_expression mult_expression unary_expression postfix_expression primary_expression
  250. %type <pNode> objectMethodCall functionCall constructor
  251. %type <pNode> objectMemberAccess arrayDereference leftVariable variable string number identifier
  252. %type <NodeType> assign_operator
  253. %type <pFormalArgs> args
  254. %type <pActualArgs> params
  255. %%
  256. /* main script rules ************************************************************************/
  257. script : vars stmtsfuncs { g_pScriptNode = NewNode( ntSTATEMENT, $1, $2 ); }
  258. | stmtsfuncs { g_pScriptNode = NewNode( ntSTATEMENT, $1, NULL ); }
  259. ;
  260. stmtsfuncs : function stmtsfuncs { $$ = $2; }
  261. | statement stmtsfuncs { $$ = NewNode( ntSTATEMENT, $1, $2 ); }
  262. | { $$ = NULL; }
  263. ;
  264. /* functions ********************************************************************************/
  265. function : FUNCTION identifier '(' args ')' functionBody { $$ = NewFunction( $6, $4, $2 ); }
  266. ;
  267. args : args ',' identifier { $$ = NewFormalArgument( $1, $3 ); }
  268. | identifier { $$ = NewFormalArgument( NULL, $1 ); }
  269. | { $$ = NULL; }
  270. ;
  271. functionBody : '{' vars statements '}' { $$ = NewNode( ntSTATEMENT, $2, $3 ); }
  272. | '{' vars '}' { $$ = $2; }
  273. | statementBlock { $$ = $1; }
  274. ;
  275. /* variable declarations ********************************************************************/
  276. vars : VAR varDeclarations ';' vars { $$ = NewNode( ntSTATEMENT, $2, $4 ); }
  277. | VAR varDeclarations ';' { $$ = $2; }
  278. ;
  279. varDeclarations : varDeclaration ',' varDeclarations { $$ = NewNode( ntVARIABLELIST, $1, $3 ); }
  280. | varDeclaration { $$ = NewNode( ntVARIABLELIST, $1, NULL ); }
  281. ;
  282. varDeclaration : identifier ASSIGN conditional_expression { $$ = NewNode( ntVARIABLE, $1, $3 ); }
  283. | identifier { $$ = NewNode( ntVARIABLE, $1, NULL ); }
  284. ;
  285. /* statements *******************************************************************************/
  286. statementBlock : '{' statements '}' { $$ = $2; }
  287. | '{' '}' { $$ = NULL; }
  288. | statement { $$ = NewNode( ntSTATEMENT, $1, NULL ); }
  289. ;
  290. statements : statement statements { $$ = NewNode( ntSTATEMENT, $1, $2 ); }
  291. | statement { $$ = NewNode( ntSTATEMENT, $1, NULL ); }
  292. ;
  293. statement : ifStatement { $$ = $1; }
  294. | forStatement { $$ = $1; }
  295. | whileStatement { $$ = $1; }
  296. | returnStatement ';' { $$ = $1; }
  297. | breakStatement ';' { $$ = $1; }
  298. | continueStatement ';' { $$ = $1; }
  299. | expression ';' { $$ = $1; }
  300. | ';' { $$ = NULL; }
  301. ;
  302. ifStatement : IF '(' expression ')' statementBlock { $$ = NewNode( ntIFSTATEMENT, $3, $5 ); }
  303. | IF '(' expression ')' statementBlock ELSE statementBlock { $$ = NewNode( ntIFSTATEMENT, $3, $5, $7 ); }
  304. ;
  305. forStatement : FOR '(' optionalExpression ';' optionalExpression ';' optionalExpression ')' statementBlock { $$ = NewNode( ntFORSTATEMENT, $3, $5, $7, $9 ); }
  306. ;
  307. whileStatement : WHILE '(' expression ')' statementBlock { $$ = NewNode( ntWHILESTATEMENT, $3, $5 ); }
  308. ;
  309. returnStatement : RETURN expression { $$ = NewNode( ntRETURNSTATEMENT, $2, NULL ); }
  310. | RETURN { $$ = NewNode( ntRETURNSTATEMENT, NULL, NULL ); }
  311. ;
  312. breakStatement : BREAK { $$ = NewNode( ntBREAKSTATEMENT, NULL, NULL ); }
  313. ;
  314. continueStatement : CONTINUE { $$ = NewNode( ntCONTINUESTATEMENT, NULL, NULL ); }
  315. ;
  316. /* expressions *******************************************************************************/
  317. optionalExpression : expression { $$ = $1; }
  318. | { $$ = NULL; }
  319. ;
  320. expression : assign_expression { $$ = $1; }
  321. | expression ',' assign_expression { $$ = NewNode( ntEXPRESSION, $1, $3 ); }
  322. ;
  323. assign_expression : conditional_expression { $$ = $1; }
  324. | leftVariable assign_operator assign_expression { $$ = NewNode( $2, $1, $3 ); }
  325. ;
  326. assign_operator : ASSIGN { $$ = ntASSIGN; }
  327. | ADDASSIGN { $$ = ntADDASSIGN; }
  328. | SUBASSIGN { $$ = ntSUBASSIGN; }
  329. | MULASSIGN { $$ = ntMULASSIGN; }
  330. | DIVASSIGN { $$ = ntDIVASSIGN; }
  331. | MODASSIGN { $$ = ntMODASSIGN; }
  332. | ANDASSIGN { $$ = ntANDASSIGN; }
  333. | ORASSIGN { $$ = ntORASSIGN; }
  334. | XORASSIGN { $$ = ntXORASSIGN; }
  335. | SHLASSIGN { $$ = ntSHLASSIGN; }
  336. | SSHRASSIGN { $$ = ntSSHRASSIGN; }
  337. ;
  338. conditional_expression : or_expression { $$ = $1; }
  339. | or_expression '?' expression ':' conditional_expression { $$ = NewNode( ntQUESTIONMARKCOLON, $1, $3, $5 ); }
  340. ;
  341. or_expression : and_expression { $$ = $1; }
  342. | or_expression LOGOR and_expression { $$ = NewNode( ntLOGOR, $1, $3 ); }
  343. ;
  344. and_expression : bitor_expression { $$ = $1; }
  345. | and_expression LOGAND bitor_expression { $$ = NewNode( ntLOGAND, $1, $3 ); }
  346. ;
  347. bitor_expression : xor_expression { $$ = $1; }
  348. | bitor_expression BITOR xor_expression { $$ = NewNode( ntBITOR, $1, $3 ); }
  349. ;
  350. xor_expression : bitand_expression { $$ = $1; }
  351. | xor_expression BITXOR bitand_expression { $$ = NewNode( ntBITXOR, $1, $3 ); }
  352. ;
  353. bitand_expression : equality_expression { $$ = $1; }
  354. | bitand_expression BITAND equality_expression { $$ = NewNode( ntBITAND, $1, $3 ); }
  355. ;
  356. equality_expression : relational_expression { $$ = $1; }
  357. | equality_expression ISEQUALS relational_expression { $$ = NewNode( ntISEQUALS, $1, $3 ); }
  358. | equality_expression ISNOTEQUALS relational_expression { $$ = NewNode( ntISNOTEQUALS, $1, $3 ); }
  359. ;
  360. relational_expression : shift_expression { $$ = $1; }
  361. | relational_expression ISLTHAN shift_expression { $$ = NewNode( ntISLTHAN, $1, $3 ); }
  362. | relational_expression ISGTHAN shift_expression { $$ = NewNode( ntISGTHAN, $1, $3 ); }
  363. | relational_expression ISLTHANEQUALS shift_expression { $$ = NewNode( ntISLTHANEQUALS, $1, $3 ); }
  364. | relational_expression ISGTHANEQUALS shift_expression { $$ = NewNode( ntISGTHANEQUALS, $1, $3 ); }
  365. ;
  366. shift_expression : add_expression { $$ = $1; }
  367. | shift_expression SHL add_expression { $$ = NewNode( ntSHL, $1, $3 ); }
  368. | shift_expression SSHR add_expression { $$ = NewNode( ntSSHR, $1, $3 ); }
  369. ;
  370. add_expression : mult_expression { $$ = $1; }
  371. | add_expression ADD mult_expression { $$ = NewNode( ntADD, $1, $3 ); }
  372. | add_expression '-' mult_expression { $$ = NewNode( ntSUB, $1, $3 ); }
  373. ;
  374. mult_expression : unary_expression { $$ = $1; }
  375. | mult_expression MUL unary_expression { $$ = NewNode( ntMUL, $1, $3 ); }
  376. | mult_expression DIV unary_expression { $$ = NewNode( ntDIV, $1, $3 ); }
  377. | mult_expression MOD unary_expression { $$ = NewNode( ntMOD, $1, $3 ); }
  378. ;
  379. unary_expression : postfix_expression { $$ = $1; }
  380. | INCREMENT unary_expression { $$ = NewNode( ntPREINCREMENT, $2, NULL ); }
  381. | DECREMENT unary_expression { $$ = NewNode( ntPREDECREMENT, $2, NULL ); }
  382. | '-' unary_expression { $$ = NewNode( ntNEGATE, $2, NULL ); }
  383. | '!' unary_expression { $$ = NewNode( ntLOGICALNOT, $2, NULL ); }
  384. | '~' unary_expression { $$ = NewNode( ntCOMPLIMENT, $2, NULL ); }
  385. ;
  386. postfix_expression : primary_expression { $$ = $1; }
  387. | postfix_expression INCREMENT { $$ = NewNode( ntPOSTINCREMENT, $1, NULL ); }
  388. | postfix_expression DECREMENT { $$ = NewNode( ntPOSTDECREMENT, $1, NULL ); }
  389. | identifier { $$ = $1; }
  390. ;
  391. primary_expression : '(' expression ')' { $$ = $2; }
  392. | objectMethodCall { $$ = $1; }
  393. | objectMemberAccess { $$ = $1; }
  394. | functionCall { $$ = $1; }
  395. | string { $$ = $1; }
  396. | number { $$ = $1; }
  397. | NEW constructor { $$ = NewNode( ntNEW, $2, NULL ); }
  398. | arrayDereference { $$ = $1; }
  399. ;
  400. /* function calls ****************************************************************************/
  401. functionCall : identifier '(' params ')' { $$ = NewNode( ntFUNCTIONCALL, $1, (LPNODE)$3 ); }
  402. ;
  403. constructor : identifier '(' params ')' { $$ = NewNode( ntCONSTRUCTOR, $1, (LPNODE)$3 ); }
  404. | identifier { $$ = NewNode( ntCONSTRUCTOR, $1, NULL ); }
  405. ;
  406. objectMethodCall : postfix_expression '.' identifier '(' params ')' { $$ = NewNode( ntOBJECTMETHODCALL, $1, $3, (LPNODE)$5 ); }
  407. ;
  408. objectMemberAccess : postfix_expression '.' identifier { $$ = NewNode( ntOBJECTMEMBERACCESS, $1, $3 ); }
  409. ;
  410. params : params ',' assign_expression { $$ = NewActualArgument( $1, $3 ); }
  411. | assign_expression { $$ = NewActualArgument( NULL, $1 ); }
  412. | { $$ = NULL; }
  413. ;
  414. /* misc left and right hand sides ************************************************************/
  415. arrayDereference : postfix_expression '[' expression ']' { $$ = NewNode( ntARRAYDEREFERENCE, $1, $3 ); }
  416. ;
  417. leftVariable : objectMemberAccess { $$ = $1; }
  418. | arrayDereference { $$ = $1; }
  419. | variable { $$ = $1; }
  420. ;
  421. variable : identifier { $$ = $1; }
  422. ;
  423. string : STRING
  424. {
  425. //strip the quotes from the string
  426. char* pszCloseQuote = &yytext[strlen(yytext)-1];
  427. *pszCloseQuote = '\0';
  428. //now search & replace escape codes
  429. char* pszScan = &yytext[1], *pszWrite = yytext;
  430. while( *pszScan != '\0' )
  431. {
  432. if( *pszScan == '\\' )
  433. switch( pszScan[1] )
  434. {
  435. case 'a': *pszWrite = '\a'; pszWrite++; pszScan+=2; break;
  436. case 'b': *pszWrite = '\b'; pszWrite++; pszScan+=2; break;
  437. case 'f': *pszWrite = '\f'; pszWrite++; pszScan+=2; break;
  438. case 'n': *pszWrite = '\n'; pszWrite++; pszScan+=2; break;
  439. case 'r': *pszWrite = '\r'; pszWrite++; pszScan+=2; break;
  440. case 't': *pszWrite = '\t'; pszWrite++; pszScan+=2; break;
  441. case 'v': *pszWrite = '\v'; pszWrite++; pszScan+=2; break;
  442. case '?': *pszWrite = '\?'; pszWrite++; pszScan+=2; break;
  443. case '\'': *pszWrite = '\''; pszWrite++; pszScan+=2; break;
  444. case '\"': *pszWrite = '\"'; pszWrite++; pszScan+=2; break;
  445. case '\\': *pszWrite = '\\'; pszWrite++; pszScan+=2; break;
  446. case '0': *pszWrite = '\0'; pszWrite++; pszScan+=2; break;
  447. default:
  448. {
  449. char szBuffer[128];
  450. sprintf( szBuffer, "Invalid escape code: %c", pszScan[1] );
  451. yyerror( szBuffer );
  452. return 0;
  453. }
  454. }
  455. else
  456. {
  457. *pszWrite = *pszScan;
  458. pszWrite++;
  459. pszScan++;
  460. }
  461. }
  462. *pszWrite = '\0';
  463. $$ = NewLeaf( ltSTRING, yytext );
  464. }
  465. ;
  466. number : OCTAL_DIGIT
  467. { $$ = NewLeaf( ltNUMBER, DecodeOctal(yytext) ); }
  468. | FLOAT_DIGIT
  469. { $$ = NewLeaf( ltFLOAT, DecodeFloat(yytext) ); }
  470. | HEX_DIGIT
  471. { $$ = NewLeaf( ltNUMBER, DecodeHex(yytext) ); }
  472. | DECIMAL_DIGIT
  473. { $$ = NewLeaf( ltNUMBER, DecodeDecimal(yytext) ); }
  474. ;
  475. identifier : IDENTIFIER
  476. {
  477. if( strlen( yytext ) >= MAX_IDENTIFIER )
  478. {
  479. char szBuffer[128];
  480. sprintf( szBuffer, "Identifier length exceeds %d characters", MAX_IDENTIFIER );
  481. yyerror( szBuffer );
  482. return 0;
  483. }
  484. $$ = NewLeaf( ltIDENTIFIER, yytext );
  485. }
  486. ;
  487. %%
  488. /* scanner declarations - DOS and Windows (MFC) *******************************************/
  489. #ifndef _WIN32
  490. #include "lex.yy.c"
  491. void yyerror( char *s ) { printf( "\nLine %d : %s\n%s\n\n", g_nLineNumber, s, yytext ); }
  492. main() { yyparse(); }
  493. #else
  494. #include <io.h>
  495. #define isatty _isatty
  496. #include "lex.yy.c"
  497. extern HWND g_hWndOwner;
  498. void yyerror( char *s )
  499. {
  500. char* pszMessage = new char[strlen(s)+strlen(yytext)+256];
  501. sprintf( pszMessage, "Line %d : %s\n%s", g_nLineNumber, s, yytext );
  502. MessageBox( g_hWndOwner, pszMessage, "Script Error", MB_ICONEXCLAMATION|MB_TASKMODAL );
  503. delete[] pszMessage;
  504. }
  505. void ResetParser()
  506. {
  507. yychar = -1;
  508. yyerrflag = 0;
  509. yynerrs = 0;
  510. YY_FLUSH_BUFFER;
  511. }
  512. void CleanupParser()
  513. {
  514. yy_delete_buffer( yy_current_buffer );
  515. free( yyss );
  516. free( yyvs );
  517. yy_current_buffer = 0;
  518. yyss = 0;
  519. yyvs = 0;
  520. }
  521. #endif