12 #define OP "+-*//&|<>="
17 if(settings
.tokens
) { printf("<class>\n"); }
19 if(has_more_tokens(pC
) == true)
24 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
27 if(strcmp(pT
, "class") == 0 ) {
28 if(settings
.tokens
) { printf("\t<keyword>%s</keyword>\n", pT
); }
30 compiler_error(40, "Incorrect Token Found: Must be 'class'", pS
, pC
, pT
);
33 /* look for class name */
34 if(has_more_tokens(pC
) == true)
39 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
42 if (tk
== IDENTIFIER
){
43 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
45 compiler_error(44, "Could Not Find Class Name or Subroutine Name at This Location", pS
, pC
, pT
);
48 /* look for '{' symbol */
49 if(has_more_tokens(pC
) == true)
54 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
58 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
60 compiler_error(44, "Could Not Find Class Name or Subroutine Name at This Location", pS
, pC
, pT
);
63 if(has_more_tokens(pC
) == true)
68 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
71 while(strcmp(pT
, "static") == 0 || strcmp(pT
, "field") == 0)
73 parse_class_var_dec();
74 if(has_more_tokens(pC
) == true)
79 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
85 if(settings
.tokens
) { printf("</class>\n"); }
88 void parse_class_var_dec()
90 if(settings
.tokens
) { printf("<classVarDec>\n"); }
92 /* look for 'static' or 'field' */
93 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
94 if(has_more_tokens(pC
) == true)
99 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
103 if(tk
== IDENTIFIER
) {
104 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
105 } else if (tk
== KEYWORD
) {
106 if(strcmp(pT
, "int") == 0 || strcmp(pT
, "char") == 0 || strcmp(pT
, "boolean") == 0) {
107 if(settings
.tokens
) { printf("\t<keyword>%s</keyword>\n", pT
); }
109 compiler_error(41, "Token Must be Data Type.", pS
, pC
, pT
);
112 compiler_error(41, "Token Must be Data Type", pS
, pC
, pT
);
115 /* look or variable name */
116 if(has_more_tokens(pC
) == true)
118 pC
= advance(pC
, pT
);
121 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
123 if(tk
== IDENTIFIER
) {
124 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
126 compiler_error(42, "Token Must be Variable Name", pS
, pC
, pT
);
130 if(has_more_tokens(pC
) == true)
132 pC
= advance(pC
, pT
);
135 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
140 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
141 if(has_more_tokens(pC
) == true)
143 pC
= advance(pC
, pT
);
146 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
148 if(tk
== IDENTIFIER
) {
149 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
151 compiler_error(42, "Token Must be Variable Name", pS
, pC
, pT
);
153 if(has_more_tokens(pC
) == true)
155 pC
= advance(pC
, pT
);
158 compiler_error(40, "Incomplete Class Declaration", pS
, pC
, pT
);
160 } while (*pT
== ',');
164 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
166 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS
, pC
, pT
);
169 if(settings
.tokens
) { printf("</classVarDec>\n"); }
172 void parse_subroutine()
174 if(settings
.tokens
) { printf("<subroutineDec>\n"); }
177 if(strcmp(pT
, "constructor") == 0 || strcmp(pT
, "function") == 0 || strcmp(pT
, "method") == 0)
179 if(settings
.tokens
) { printf("\t<keyword>%s</keyword>\n", pT
); }
181 compiler_error(8, "Incorrect Token Found: Must be 'constructor', 'function', or 'method'", pS
, pC
, pT
);
185 /* look for return type of function */
186 if(has_more_tokens(pC
) == true)
188 pC
= advance(pC
, pT
);
190 if(tk
== KEYWORD
|| tk
== IDENTIFIER
)
192 if(strcmp(pT
, "void") == 0)
194 if(settings
.tokens
) { printf("\t<keyword>%s</keyword>\n", pT
); }
196 if(settings
.tokens
) { printf("\t<type>%s</type>\n", pT
); }
199 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS
, pC
, pT
);
202 compiler_error(29, "Incorrect Token Type", pS
, pC
, pT
);
205 /* look for subroutine name */
206 if(has_more_tokens(pC
) == true)
208 pC
= advance(pC
, pT
);
212 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
214 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS
, pC
, pT
);
217 compiler_error(10, "Incorrect Token Type. Looking for Keyword or Identifier.", pS
, pC
, pT
);
220 /* look for symbol '(' that specifies beginning of parameter list */
221 if(has_more_tokens(pC
) == true)
223 pC
= advance(pC
, pT
);
227 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
230 compiler_error(12, "Parameter List for Function Missing", pS
, pC
, pT
);
233 compiler_error(11, "Name of Function Must be an Identifier", pS
, pC
, pT
);
236 /* look for end of parameter list */
239 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
241 compiler_error(13, "Could Not Complete Parameter List for Function", pS
, pC
, pT
);
244 /* look for opening brace for block */
245 if(has_more_tokens(pC
) == true)
247 pC
= advance(pC
, pT
);
251 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
252 if(has_more_tokens(pC
) == true)
254 pC
= advance(pC
, pT
);
257 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS
, pC
, pT
);
262 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS
, pC
, pT
);
265 while(strcmp(pT
, "let") == 0 || strcmp(pT
, "if") == 0 || strcmp(pT
, "while") == 0 || strcmp(pT
, "do") == 0 || strcmp(pT
, "return") == 0)
268 if(has_more_tokens(pC
) == true)
270 pC
= advance(pC
, pT
);
273 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS
, pC
, pT
);
277 if(settings
.tokens
) { printf("</subroutineDec>\n"); }
282 if(*pT
== '(') { if(settings
.tokens
) { printf("<parameterList>\n"); } }
284 /* look for datatype in parameter list */
285 if(has_more_tokens(pC
) == true)
287 pC
= advance(pC
, pT
);
290 if(strcmp(pT
, "int") == 0 || strcmp(pT
, "char") == 0 || strcmp(pT
, "boolean") == 0)
292 if(settings
.tokens
) { printf("\t<keyword>%s</keyword>\n", pT
); }
294 compiler_error(14, "Incorrect Token Type in Parameter List. Looking for Datatype name.", pS
, pC
, pT
);
296 } else if(tk
== SYMBOL
&& *pT
== ')') { if(settings
.tokens
) { printf("</parameterList>\n"); } return; }
298 compiler_error(13, "Could Not Complete Parameter List for Function", pS
, pC
, pT
);
301 /* look for identifier for this parameter */
302 if(has_more_tokens(pC
) == true)
304 pC
= advance(pC
, pT
);
306 if(tk
== IDENTIFIER
) {
307 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
310 compiler_error(15, "Incorrect Token Type in Parameter List. Looking for Variable Identifier.", pS
, pC
, pT
);
313 compiler_error(13, "Could Not Complete Parameter List for Function", pS
, pC
, pT
);
316 /* are there more parameters? */
317 if(has_more_tokens(pC
) == true)
319 pC
= advance(pC
, pT
);
323 } else if (*pT
== ')') { /* exit parse_params */
324 if(settings
.tokens
) { printf("</parameterList>\n"); }
327 compiler_error(16, "Incorrect Token Type in Parameter List. Looking for ',' or ')'", pS
, pC
, pT
);
330 compiler_error(13, "Could Not Complete Parameter List for Function", pS
, pC
, pT
);
336 /* look for token named 'var' */
337 if(strcmp(pT
, "var") == 0)
339 if(settings
.tokens
) { printf("<varDec>\n\t<symbol>%s</symbol>\n", pT
); }
342 /* look for variable data type */
343 if(has_more_tokens(pC
) == true)
345 pC
= advance(pC
, pT
);
347 if(strcmp(pT
, "int") == 0 || strcmp(pT
, "char") == 0 || strcmp(pT
, "boolean") == 0 || strcmp(pT
, "Array") == 0)
349 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
351 } else if (tk
== IDENTIFIER
) { /* could also be a custom class name */
352 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
354 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS
, pC
, pT
);
358 /* look for identifier(s) for variable(s) */
360 if(has_more_tokens(pC
) == true)
362 pC
= advance(pC
, pT
);
365 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS
, pC
, pT
);
369 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
372 if(has_more_tokens(pC
) == true)
374 pC
= advance(pC
, pT
);
377 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS
, pC
, pT
);
381 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
383 } while (*pT
== ',');
385 if(has_more_tokens(pC
) == true)
387 pC
= advance(pC
, pT
);
390 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS
, pC
, pT
);
395 void parse_statements()
397 if(strcmp(pT
, "let") == 0)
400 } else if(strcmp(pT
, "if") == 0)
403 } else if(strcmp(pT
, "while") == 0)
406 } else if(strcmp(pT
, "do") == 0)
409 } else if(strcmp(pT
, "return") == 0)
417 if(settings
.tokens
) { printf("<doStatement>\n\t<keyword>do</keyword>\n"); }
418 if(has_more_tokens(pC
) == true)
420 pC
= advance(pC
, pT
);
423 compiler_error(20, "Could Not Complete Do Statement. Incomplete Program", pS
, pC
, pT
);
426 /* must be an identifier */
427 if(tk
== IDENTIFIER
) {
428 parse_subroutine_call();
430 compiler_error(30, "Subroutine Name Must Be Listed Here", pS
, pC
, pT
);
433 if(settings
.tokens
) { printf("</doStatement>\n"); }
438 if(settings
.tokens
) { printf("<letStatement>\n\t<keyword>let</keyword>\n"); }
439 if(has_more_tokens(pC
) == true)
441 pC
= advance(pC
, pT
);
444 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS
, pC
, pT
);
447 /* look for an identifier - must be a variable name */
450 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
452 compiler_error(31, "Could Not Find Identifier At This Location", pS
, pC
, pT
);
455 /* optional '[' for an array offset value */
456 if(has_more_tokens(pC
) == true)
458 pC
= advance(pC
, pT
);
461 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS
, pC
, pT
);
466 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
472 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
478 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
480 compiler_error(32, "Could Not Find '=' Symbol At This Location", pS
, pC
, pT
);
483 /* parse_expression(); */
485 /* look for identifier */
486 if(has_more_tokens(pC
) == true)
488 pC
= advance(pC
, pT
);
491 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS
, pC
, pT
);
496 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
498 compiler_error(20, "Could Not Find ';' Symbol At This Location", pS
, pC
, pT
);
502 if(has_more_tokens(pC
) == true)
504 pC
= advance(pC
, pT
);
507 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS
, pC
, pT
);
512 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
514 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS
, pC
, pT
);
517 if(settings
.tokens
) { printf("</letStatement>\n"); }
523 exit_error(0, "Parsing While");
528 if(settings
.tokens
) { printf("<returnStatement>\n\t<identifier>%s</identifier>\n", pT
); }
531 if(has_more_tokens(pC
) == true)
533 pC
= advance(pC
, pT
);
536 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS
, pC
, pT
);
539 if (*pT
!= ';') { parse_expression(); }
543 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
545 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS
, pC
, pT
);
547 if(settings
.tokens
) { printf("</returnStatement>\n"); }
552 exit_error(0, "Parsing If");
555 void parse_expression()
559 if(has_more_tokens(pC
) == true)
561 pC
= advance(pC
, pT
);
564 compiler_error(34, "Could Not Parse Expression. Incomplete Program", pS
, pC
, pT
);
567 if(strchr(OP
, *pT
) != NULL
)
569 if(settings
.tokens
) { printf("<operator>%s</operator>\n", pT
); }
570 if(has_more_tokens(pC
) == true)
572 pC
= advance(pC
, pT
);
575 compiler_error(34, "Could Not Parse Expression. Incomplete Program", pS
, pC
, pT
);
585 if(settings
.tokens
) { printf("<integerConst>%s</intConst>\n", pT
); }
589 if(strchr(UNARY_OP
, *pT
) != NULL
)
591 if(settings
.tokens
) { printf("<unaryOperator>%s</unaryOperator>\n", pT
); }
592 if(has_more_tokens(pC
) == true)
594 pC
= advance(pC
, pT
);
598 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS
, pC
, pT
);
605 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
607 if(has_more_tokens(pC
) == true)
609 pC
= advance(pC
, pT
);
613 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
615 compiler_error(26, "Improperly Terminated Array Expression. Symbol ']' Required at this Location.", pS
, pC
, pT
);
618 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS
, pC
, pT
);
622 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
623 if(has_more_tokens(pC
) == true)
625 pC
= advance(pC
, pT
);
628 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS
, pC
, pT
);
633 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
635 compiler_error(38, "Could Not Find Symbol ')' At This Location", pS
, pC
, pT
);
639 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
646 void parse_subroutine_call()
648 if(settings
.tokens
) { printf("<subroutineCall>\n"); }
651 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
653 compiler_error(35, "Could Not Find Class Name or Subroutine Name at This Location", pS
, pC
, pT
);
656 if(has_more_tokens(pC
) == true)
658 pC
= advance(pC
, pT
);
661 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS
, pC
, pT
);
665 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
666 if(has_more_tokens(pC
) == true)
668 pC
= advance(pC
, pT
);
671 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS
, pC
, pT
);
675 if(settings
.tokens
) { printf("\t<identifier>%s</identifier>\n", pT
); }
677 compiler_error(37, "Could Not Find Method Name or Subroutine Name at This Location", pS
, pC
, pT
);
681 if(*pT
!= '(') /* this for calls with no class name at beginning */
683 if(has_more_tokens(pC
) == true)
685 pC
= advance(pC
, pT
);
688 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS
, pC
, pT
);
694 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
695 if(has_more_tokens(pC
) == true)
697 pC
= advance(pC
, pT
);
700 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS
, pC
, pT
);
706 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
707 if(has_more_tokens(pC
) == true)
709 pC
= advance(pC
, pT
);
712 compiler_error(38, "Could Not Find Symbol ')' At This Location", pS
, pC
, pT
);
716 compiler_error(39, "Could Not Find Symbol '(' At This Location", pS
, pC
, pT
);
721 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
724 if(settings
.tokens
) { printf("<subroutineCall>\n"); }
727 void parse_expr_lst()
733 if(settings
.tokens
) { printf("\t<symbol>%s</symbol>\n", pT
); }
734 if(has_more_tokens(pC
) == true)
736 pC
= advance(pC
, pT
);
739 compiler_error(24, "Could Not Complete Expression List. Incomplete Program", pS
, pC
, pT
);