PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/cs48.y

https://github.com/jconnell/CS48-Compiler---New
Happy | 795 lines | 743 code | 52 blank | 0 comment | 0 complexity | 392f3939b6e4ff779e96f5ef40b77729 MD5 | raw file
  1. /*
  2. By David Kopec and Jonathan Connell for CS 48
  3. This defines the bison input for our compiler.
  4. The parser contained herein complies with all of the
  5. grammar rules of C48.
  6. Small parts of this file are based on tiny.y from the appendix to
  7. the Louden book.
  8. */
  9. %{
  10. #define YYPARSER /* distinguishes Yacc output from other code files */
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "tokens.h" /* from the lexer */
  15. #include "ast.h" /* for the node definitions and functions */
  16. /*for verbose errors*/
  17. #define YYERROR_VERBOSE 1
  18. #define YYSTYPE ast_node
  19. static ast_node savedTree; /* stores syntax tree for later return */
  20. extern char *yytext; /*the token's text from the lexxer*/
  21. %}
  22. /* make sure these values match up with the lexxer ones in lexer.l */
  23. %token IF 258
  24. %token ELSE 259
  25. %token READ 260
  26. %token WRITE 261
  27. %token BANG 262
  28. %token EQUALS 263
  29. %token NOTEQUALS 264
  30. %token GREATER 265
  31. %token GREATEREQ 266
  32. %token LESS 267
  33. %token LESSEQ 268
  34. %token DO 269
  35. %token WHILE 270
  36. %token FOR 271
  37. %token LPAREN 272
  38. %token RPAREN 273
  39. %token LBRACKET 274
  40. %token RBRACKET 275
  41. %token AND 276
  42. %token OR 277
  43. %token SEMI 278
  44. %token INT 279
  45. %token DOUBLE 280
  46. %token CHAR 281
  47. %token SWITCH 282
  48. %token CASE 283
  49. %token CONST 284
  50. %token CONTINUE 285
  51. %token DEFAULT 286
  52. %token RETURN 287
  53. %token SIZEOF 288
  54. %token STATIC 289
  55. %token VOID 290
  56. %token BREAK 291
  57. %token INCR 292
  58. %token DECR 293
  59. %token COMMENT 294
  60. %token INUM 295
  61. %token ID 296
  62. %token DIVIDE 297
  63. %token ASSIGN 298
  64. %token MULTIPLY 299
  65. %token ADD 300
  66. %token SUBTRACT 301
  67. %token FNUM 302
  68. %token STRING 303
  69. /*set precedences of operations*/
  70. %right ASSIGN
  71. %left OR
  72. %left AND
  73. %left EQUALS NOTEQUALS
  74. %left LESS GREATER LESSEQ GREATEREQ
  75. %left ADD SUBTRACT
  76. %left MULTIPLY DIVIDE
  77. %right BANG DECR INCR
  78. %% /* Grammar for C 48 based on website grammar with some modifications and additions*/
  79. /*at the start of the program we have a root node and the first sequence, this is just
  80. how we start every program*/
  81. program : declaration_list
  82. {
  83. $$ = createNode(ROOT);
  84. /*root must have a sequence as a child
  85. and that sequence will have all the declarations*/
  86. $$->left_child = createNode(SEQ);
  87. $$->left_child->left_child = $1;
  88. savedTree = $$;
  89. }
  90. ;
  91. /*left recursion is common in this grammar and we always do it the same way;
  92. by going through the right_siblings until we find one that is null*/
  93. declaration_list : declaration_list declaration
  94. { YYSTYPE t = $1;
  95. if (t != NULL)
  96. { while (t->right_sibling != NULL)
  97. t = t->right_sibling;
  98. t->right_sibling = $2;
  99. $$ = $1;
  100. }
  101. else $$ = $2;
  102. }
  103. | declaration
  104. { $$ = $1; }
  105. ;
  106. /*whenever something is just a direct transfer from one rule to the next
  107. you will see this construct of $$ = $1*/
  108. declaration : var_declaration
  109. { $$ = $1; }
  110. | func_declaration
  111. { $$ = $1; }
  112. ;
  113. /*if it has an ARRAY_SIZE as a child, then we know that's
  114. an array and we do an array declare,
  115. otherwise it's just a regular declare*/
  116. var_declaration : INT var_decl_list ';'
  117. {
  118. /*check for any ARRAY_SIZE nodes and declare those differently*/
  119. YYSTYPE t = $2;
  120. /*this is just a dummy that will get overwritten*/
  121. $$ = createNode(INT_DEC);
  122. YYSTYPE v = $$;
  123. while(t != NULL)
  124. {
  125. /*if the ARRAY_SIZE thing is where expected, then we do an array dec*/
  126. if(t->left_child != NULL && t->left_child->node_type == ARRAY_SIZE)
  127. {
  128. v->right_sibling = createNode(INT_ARRAY_DEC);
  129. v->right_sibling->left_child = t;
  130. t=t->right_sibling;
  131. v->right_sibling->left_child->right_sibling = NULL;
  132. }
  133. else
  134. {
  135. v->right_sibling = createNode(INT_DEC);
  136. v->right_sibling->left_child = t;
  137. t=t->right_sibling;
  138. v->right_sibling->left_child->right_sibling = NULL;
  139. }
  140. v=v->right_sibling;
  141. }
  142. /*cleanup overwrite dummy original v and start where the good stuff starts*/
  143. v = $$;
  144. $$ = $$->right_sibling;
  145. free(v);
  146. }
  147. | DOUBLE var_decl_list ';'
  148. {
  149. /*check for any ARRAY_SIZE nodes and declare those differently*/
  150. YYSTYPE t = $2;
  151. /*this is just a dummy that will get overwritten*/
  152. $$ = createNode(DOU_DEC);
  153. YYSTYPE v = $$;
  154. while(t != NULL)
  155. {
  156. /*if the ARRAY_SIZE thing is where expected, then we do an array dec*/
  157. if(t->left_child != NULL && t->left_child->node_type == ARRAY_SIZE)
  158. {
  159. v->right_sibling = createNode(DOU_ARRAY_DEC);
  160. v->right_sibling->left_child = t;
  161. t=t->right_sibling;
  162. v->right_sibling->left_child->right_sibling = NULL;
  163. }
  164. else
  165. {
  166. v->right_sibling = createNode(DOU_DEC);
  167. v->right_sibling->left_child = t;
  168. t=t->right_sibling;
  169. v->right_sibling->left_child->right_sibling = NULL;
  170. }
  171. v=v->right_sibling;
  172. }
  173. /*cleanup overwrite dummy original v*/
  174. v = $$;
  175. $$ = $$->right_sibling;
  176. free(v);
  177. }
  178. ;
  179. /*again, this is like the last left recursion*/
  180. var_decl_list : var_decl_list ',' var_decl
  181. { YYSTYPE t = $1;
  182. if (t != NULL)
  183. { while (t->right_sibling != NULL)
  184. t = t->right_sibling;
  185. t->right_sibling = $3;
  186. $$ = $1;
  187. }
  188. else $$ = $3;
  189. }
  190. | var_decl
  191. {$$ = $1;}
  192. ;
  193. /*an edifier is just a convenient way of making an IDENTIFIER when we see
  194. an ID token*/
  195. idifier : ID
  196. {
  197. $$ = createNode(IDENTIFIER);
  198. $$->value.string =
  199. copyString(yytext);
  200. }
  201. ;
  202. /*the size of the declared array*/
  203. arraylen : INUM
  204. {
  205. $$ = createNode(INT_LITERAL);
  206. $$->value.int_value = atoi(yytext);
  207. }
  208. ;
  209. /*if an ID after a declaration has a left child that is an expression then it should be
  210. turned into an assign quad in quads.c after the variable is declared*/
  211. var_decl : idifier
  212. {
  213. $$ = $1;
  214. }
  215. /*we must check for dangling assignments in quads when we're doing
  216. variable declarations - if the id has a child then
  217. we should be assigning it that value as a quad*/
  218. | idifier ASSIGN expression
  219. {
  220. $$ = $1;
  221. $$->left_child = $3;
  222. }
  223. | idifier '[' arraylen ']'
  224. /*we're going to have to check for an ARRAY_SIZE node to see if it's an array dec*/
  225. {
  226. $$ = $1;
  227. $$->left_child = createNode(ARRAY_SIZE);
  228. $$->left_child->left_child = $3;
  229. }
  230. ;
  231. /*we're not worrying about return types, our bad, but
  232. formal params are just dummies since we worry about the params only in the
  233. caller as in Louden. We do however need to store the compound_statement, since this
  234. is what will actually get executed later!*/
  235. func_declaration : INT idifier '(' formal_params ')' compound_statement
  236. {
  237. $$ = createNode(FUNC_DEF);
  238. $$->left_child = $2;
  239. $$->left_child->right_sibling = $4;
  240. $$->left_child->right_sibling->right_sibling = $6;
  241. }
  242. | DOUBLE idifier '(' formal_params ')' compound_statement
  243. {
  244. $$ = createNode(FUNC_DEF);
  245. $$->left_child = $2;
  246. $$->left_child->right_sibling = $4;
  247. $$->left_child->right_sibling->right_sibling = $6;
  248. }
  249. | VOID idifier '(' formal_params ')' compound_statement
  250. {
  251. $$ = createNode(FUNC_DEF);
  252. $$->left_child = $2;
  253. $$->left_child->right_sibling = $4;
  254. $$->left_child->right_sibling->right_sibling = $6;
  255. }
  256. ;
  257. /*this is those empty params*/
  258. formal_params : formal_list {$$ = $1;}
  259. /*just put a blank param in*/
  260. | VOID {$$ = createNode(FUNC_PARAM);}
  261. | {$$ = createNode(FUNC_PARAM);}
  262. ;
  263. /* lists of empties */
  264. formal_list : formal_list ',' formal_param
  265. { YYSTYPE t = $1;
  266. if (t != NULL)
  267. { while (t->right_sibling != NULL)
  268. t = t->right_sibling;
  269. t->right_sibling = $3;
  270. $$ = $1;
  271. }
  272. else $$ = $3;
  273. }
  274. | formal_param
  275. {$$ = $1;}
  276. ;
  277. /*we skip over these currently in quads since we only
  278. look at this at the point of call, so we'll just put blank
  279. ones here */
  280. formal_param : INT idifier
  281. {$$ = createNode(FUNC_PARAM);}
  282. | DOUBLE idifier
  283. {$$ = createNode(FUNC_PARAM);}
  284. | INT idifier '[' ']'
  285. {$$ = createNode(FUNC_PARAM);}
  286. | DOUBLE idifier '[' ']'
  287. {$$ = createNode(FUNC_PARAM);}
  288. ;
  289. /*this should be a sequence with both nonterminals as children
  290. since they are both lists*/
  291. compound_statement : '{' local_declarations statement_list '}'
  292. {
  293. $$ = createNode(SEQ);
  294. $$->left_child = $2;
  295. YYSTYPE t = $2;
  296. if (t != NULL)
  297. { while (t->right_sibling != NULL)
  298. t = t->right_sibling;
  299. t->right_sibling = $3;
  300. }
  301. else
  302. $$->left_child = $3;
  303. }
  304. ;
  305. /* same left recursion shizzle again */
  306. local_declarations : local_declarations var_declaration
  307. { YYSTYPE t = $1;
  308. if (t != NULL)
  309. { while (t->right_sibling != NULL)
  310. t = t->right_sibling;
  311. t->right_sibling = $2;
  312. $$ = $1;
  313. }
  314. else $$ = $2;
  315. }
  316. |
  317. {
  318. $$ = NULL;
  319. }
  320. ;
  321. /* and yet again */
  322. statement_list : statement_list statement
  323. { YYSTYPE t = $1;
  324. if (t != NULL)
  325. { while (t->right_sibling != NULL)
  326. t = t->right_sibling;
  327. t->right_sibling = $2;
  328. $$ = $1;
  329. }
  330. else $$ = $2;
  331. }
  332. |
  333. {
  334. $$ = NULL;
  335. }
  336. ;
  337. /* just basic one to ones */
  338. statement : expression_statement
  339. { $$ = $1; }
  340. | compound_statement
  341. { $$ = $1; }
  342. | if_statement
  343. { $$ = $1; }
  344. | while_statement
  345. { $$ = $1; }
  346. | do_while_statement
  347. { $$ = $1; }
  348. | for_statement
  349. { $$ = $1; }
  350. | return_statement
  351. { $$ = $1; }
  352. | read_statement
  353. { $$ = $1; }
  354. | write_statement
  355. { $$ = $1; }
  356. | switch_statement
  357. { $$ = $1; }
  358. ;
  359. /*switch statement is an addition the original grammar, it features
  360. a var that's compared and a list of cases*/
  361. switch_statement : SWITCH '(' var ')' '{' cases '}'
  362. {
  363. $$ = createNode(SWITCH_ST);
  364. $$->left_child = $3;
  365. $$->left_child->right_sibling = $6;
  366. printf("created switch\n");
  367. }
  368. ;
  369. /*same left recursion as before */
  370. cases : cases acase
  371. {
  372. YYSTYPE t = $1;
  373. if (t != NULL)
  374. { while (t->right_sibling != NULL)
  375. t = t->right_sibling;
  376. t->right_sibling = $2;
  377. $$ = $1;
  378. }
  379. else $$ = $2;
  380. }
  381. | acase
  382. {$$ = $1;}
  383. ;
  384. /* a comparison can be a literal or a variable */
  385. casecompare : var
  386. {$$ = $1;}
  387. | INUM
  388. {$$ = createNode(INT_LITERAL);
  389. $$->value.int_value = atoi(yytext);}
  390. | FNUM
  391. {$$ = createNode(DOUBLE_LITERAL);
  392. $$->value.double_value = atof(yytext);}
  393. ;
  394. /*all cases have a list of statement if the comparison is true to execute,
  395. the last case is always default*/
  396. acase : CASE casecompare ':' statement_list
  397. {
  398. $$ = createNode(SWITCH_CASE);
  399. $$->left_child = $2;
  400. $$->left_child->right_sibling = $4;
  401. }
  402. /*we always process the default in quads, and it's always last, unless there was a break to stop us
  403. so we'll just make it a sequence*/
  404. | DEFAULT ':' statement_list
  405. {
  406. $$ = createNode(SEQ);
  407. $$->left_child = $3;
  408. }
  409. ;
  410. /*expressions sometimes need to end in semicolon, here it is*/
  411. expression_statement : expression ';'
  412. { $$ = $1; }
  413. | ';'
  414. { $$ = NULL;}
  415. ;
  416. /*left child is the evaluation, left child->right sibling
  417. is what to do if the evaluation is true,
  418. if_else adds additionally another child to do if the statement
  419. is false and only if it's false*/
  420. if_statement : IF '(' expression ')' statement
  421. { $$ = createNode(IF_S);
  422. $$->left_child = $3;
  423. $$->left_child->right_sibling = $5;
  424. }
  425. | IF '(' expression ')' statement ELSE statement
  426. { $$ = createNode(IF_ELSE);
  427. $$->left_child = $3;
  428. $$->left_child->right_sibling = $5;
  429. $$->left_child->right_sibling->right_sibling = $7;
  430. }
  431. ;
  432. /*left_child is the expression, right_sibling is what to execute while it's true*/
  433. while_statement : WHILE '(' expression ')' statement
  434. {
  435. $$ = createNode(WHILE_LOOP);
  436. $$->left_child = $3;
  437. $$->left_child->right_sibling = $5;
  438. }
  439. ;
  440. /*quads still expects the expression as the left_child, so we keep it there
  441. and this is the same as for a WHILE loop almost*/
  442. do_while_statement : DO statement WHILE '(' expression ')' ';'
  443. {
  444. $$ = createNode(DO_WHILE_LOOP);
  445. $$->left_child = $5;
  446. $$->left_child->right_sibling = $2;
  447. }
  448. ;
  449. /* quads expects the fore_header_expressions in order followed by the statement */
  450. for_statement : FOR '(' for_header_expression ';' for_header_expression ';' for_header_expression ')' statement
  451. {
  452. $$ = createNode(FOR_LOOP);
  453. $$->left_child = $3;
  454. $$->left_child->right_sibling = $5;
  455. $$->left_child->right_sibling->right_sibling = $7;
  456. $$->left_child->right_sibling->right_sibling->right_sibling = $9;
  457. }
  458. ;
  459. /* we can't have null, so we just put a one in when nothing is entered */
  460. for_header_expression : expression
  461. {$$ = $1;}
  462. |
  463. {
  464. $$ = createNode(INT_LITERAL);
  465. }
  466. ;
  467. /*if there is something to return, we put it as the
  468. child of the return node*/
  469. return_statement : RETURN ';'
  470. {$$ = createNode(RETURN_S);}
  471. | RETURN expression ';'
  472. {$$ = createNode(RETURN_S);
  473. $$->left_child = $2;}
  474. ;
  475. /*read has whatever is being read into as a child*/
  476. read_statement : READ var ';'
  477. {
  478. $$ = createNode(READ_S);
  479. $$->left_child = $2;
  480. }
  481. ;
  482. /*we just create a node with the string as its value*/
  483. strl : STRING
  484. {
  485. $$ = createNode(STRING_LITERAL);
  486. $$->value.string =
  487. copyString(yytext);
  488. }
  489. ;
  490. /*write has what's being written as its child*/
  491. write_statement : WRITE expression ';'
  492. {
  493. $$ = createNode(WRITE_S);
  494. $$->left_child = $2;
  495. }
  496. | WRITE strl ';'
  497. {
  498. $$ = createNode(WRITE_S);
  499. $$->left_child = $2;
  500. }
  501. ;
  502. /*an expression can be an assignment to a var*/
  503. expression : var ASSIGN expression
  504. {
  505. $$ = createNode(OP_ASSIGN);
  506. $$->left_child = $1;
  507. $$->left_child->right_sibling = $3;
  508. }
  509. /*r-value covers most expressions*/
  510. | r_value
  511. { $$ = $1; }
  512. ;
  513. /*a var is an array pull or just an id*/
  514. var : idifier
  515. {$$ = $1;}
  516. /*ID is the first child, the index into it is the second*/
  517. | idifier '[' expression ']'
  518. {
  519. $$ = createNode(ARRAY_PULL);
  520. $$->left_child = $1;
  521. $$->left_child->right_sibling = $3;
  522. }
  523. ;
  524. /*these are all pretty self explanatory;
  525. the children are the operands of each operation*/
  526. r_value : expression ADD expression
  527. {
  528. $$ = createNode(OP_PLUS);
  529. $$->left_child = $1;
  530. $$->left_child->right_sibling = $3;
  531. }
  532. | expression SUBTRACT expression
  533. {
  534. $$ = createNode(OP_MINUS);
  535. $$->left_child = $1;
  536. $$->left_child->right_sibling = $3;
  537. }
  538. | expression MULTIPLY expression
  539. {
  540. $$ = createNode(OP_TIMES);
  541. $$->left_child = $1;
  542. $$->left_child->right_sibling = $3;
  543. }
  544. | expression DIVIDE expression
  545. {
  546. $$ = createNode(OP_DIVIDE);
  547. $$->left_child = $1;
  548. $$->left_child->right_sibling = $3;
  549. }
  550. | expression LESS expression
  551. {
  552. $$ = createNode(OP_LESS_THAN);
  553. $$->left_child = $1;
  554. $$->left_child->right_sibling = $3;
  555. }
  556. | expression LESSEQ expression
  557. {
  558. $$ = createNode(OP_LESS_EQUALS);
  559. $$->left_child = $1;
  560. $$->left_child->right_sibling = $3;
  561. }
  562. | expression GREATER expression
  563. {
  564. $$ = createNode(OP_GREATER_THAN);
  565. $$->left_child = $1;
  566. $$->left_child->right_sibling = $3;
  567. }
  568. | expression GREATEREQ expression
  569. {
  570. $$ = createNode(OP_GREATER_EQUALS);
  571. $$->left_child = $1;
  572. $$->left_child->right_sibling = $3;
  573. }
  574. | expression EQUALS expression
  575. {
  576. $$ = createNode(OP_EQUALS);
  577. $$->left_child = $1;
  578. $$->left_child->right_sibling = $3;
  579. }
  580. | expression NOTEQUALS expression
  581. {
  582. $$ = createNode(OP_NOT_EQUALS);
  583. $$->left_child = $1;
  584. $$->left_child->right_sibling = $3;
  585. }
  586. | expression AND expression
  587. {
  588. $$ = createNode(OP_AND);
  589. $$->left_child = $1;
  590. $$->left_child->right_sibling = $3;
  591. }
  592. | expression OR expression
  593. {
  594. $$ = createNode(OP_OR);
  595. $$->left_child = $1;
  596. $$->left_child->right_sibling = $3;
  597. }
  598. | BANG expression
  599. {
  600. $$ = createNode(OP_NOT);
  601. $$->left_child = $2;
  602. }
  603. | SUBTRACT expression
  604. {
  605. $$ = createNode(OP_NEGATIVE);
  606. $$->left_child = $2;
  607. }
  608. | var
  609. {$$ = $1;}
  610. | INCR expression
  611. {
  612. $$ = createNode(OP_PRE_INCR);
  613. $$->left_child = $2;
  614. }
  615. | DECR expression
  616. {
  617. $$ = createNode(OP_PRE_DECR);
  618. $$->left_child = $2;
  619. }
  620. | expression INCR
  621. {
  622. $$ = createNode(OP_POST_INCR);
  623. $$->left_child = $1;
  624. }
  625. | expression DECR
  626. {
  627. $$ = createNode(OP_POST_DECR);
  628. $$->left_child = $1;
  629. }
  630. | '(' expression ')'
  631. { $$ = $2; }
  632. | SIZEOF '(' var ')'
  633. {
  634. $$ = createNode(OP_SIZEOF);
  635. $$->left_child = $3;
  636. }
  637. | call
  638. { $$ = $1; }
  639. | INUM
  640. {
  641. $$ = createNode(INT_LITERAL);
  642. $$->value.int_value = atoi(yytext);
  643. }
  644. | FNUM
  645. {
  646. $$ = createNode(DOUBLE_LITERAL);
  647. $$->value.double_value = atof(yytext);
  648. }
  649. | CONTINUE
  650. {$$ = createNode(CONTINUE_ST);}
  651. | BREAK
  652. {$$ = createNode(BREAK_ST);}
  653. ;
  654. /* every child is a function parameter and each of its children is the expression that
  655. represents the actual parameter; if the function is called with no parameters it
  656. just gets a blank FUNC_PARAM, because quads expects that (old design)*/
  657. call : idifier '(' args ')'
  658. {
  659. $$ = createNode(FUNC_CALL);
  660. /*as per quads, we put params first, then id*/
  661. $$->left_child = createNode(FUNC_PARAM);
  662. YYSTYPE t = $3;
  663. YYSTYPE v = $$->left_child;
  664. if (t != NULL)
  665. {
  666. $$->left_child->left_child = t;
  667. while (t->right_sibling != NULL)
  668. {
  669. YYSTYPE r = t->right_sibling;
  670. t->right_sibling = NULL;
  671. v->right_sibling = createNode(FUNC_PARAM);
  672. v->right_sibling->left_child = r;
  673. t = r;
  674. v=v->right_sibling;
  675. }
  676. v->right_sibling = $1;
  677. }
  678. else
  679. $$->left_child->right_sibling = $1;
  680. }
  681. ;
  682. /*left recursive argument list will follow, this is the prepper*/
  683. args : arg_list
  684. { $$ = $1; }
  685. |
  686. { $$ = NULL; }
  687. ;
  688. /*each of these args actually needs to be in the format of a function param
  689. so we need to wrap them in there somehow, still thinking*/
  690. arg_list : arg_list ',' expression
  691. { YYSTYPE t = $1;
  692. if (t != NULL)
  693. { while (t->right_sibling != NULL)
  694. t = t->right_sibling;
  695. t->right_sibling = $3;
  696. $$ = $1;
  697. }
  698. else $$ = $3;
  699. }
  700. | expression
  701. {
  702. $$ = $1;
  703. }
  704. ;
  705. %%
  706. /*print out the syntax error and what line it occurred on*/
  707. int yyerror(char * message)
  708. { printf("Syntax error at line %d: %s\n",lineno,message);
  709. printf("Current token: %s\n", yytext);
  710. //printToken(yychar,yytext);
  711. //Error = TRUE;
  712. return 0;
  713. }
  714. /*yparse() is called which will continue and call yylex() until
  715. it reaches the end of the file*/
  716. ast_node doParse(void)
  717. {
  718. printf("doparse in cs48.y called\n");
  719. printf("yyparse returned %d\n\n", yyparse());
  720. return savedTree;
  721. }
  722. /* Function copyString allocates and makes a new
  723. * copy of an existing string
  724. from Louden
  725. */
  726. char * copyString(char * s)
  727. { int n;
  728. char * t;
  729. if (s==NULL) return NULL;
  730. n = strlen(s)+1;
  731. t = malloc(n);
  732. if (t==NULL)
  733. fprintf(listing,"Out of memory error at line %d\n",lineno);
  734. else strcpy(t,s);
  735. return t;
  736. }
  737. /*create a node of type type with its children set to NULL*/
  738. ast_node createNode(int type)
  739. {
  740. ast_node new_node = malloc(sizeof(struct ast_node_struct));
  741. new_node->left_child = new_node->right_sibling = NULL;
  742. new_node->node_type = type;
  743. }