int main(int argc, char *argv[]) { // Declare a pointer to the input file FILE *inFile; // Declare a pointer to the root file name char *rootName; // Declare pointers to the head and tail of the symbol table DEF_NODE *head, *tail; // Set head and tail to NULL head = tail = NULL; // Initialize the errorIndex to 0 errorIndex = 0; // Find the root file name and set it rootName = (char *)findRootFileName(argv[IN_FILE]); // Try to open the input file for reading if((inFile = fopen(argv[IN_FILE], "r")) == NULL) { // Print error message if file could not be opened fprintf(stderr, "Could not open file: %s\n", argv[IN_FILE]); // Fatal error, exit program exit(1); } // Initialize all the opcodes initOpcodes(); // Do the first pass and build the symbol table passOne(inFile, &head, &tail); // Rewind the input file so it is ready for the second pass rewind(inFile); // Do the second pass and check for errors passTwo(inFile, &head, &tail); // If there were errors in the input file... if(errorIndex > 0) { // Make an error file writeErrFile(inFile, rootName); } // There were no errors in the input file else { // Write the symbol table file printST(head, rootName); // Write the object code file writeObjFile(rootName); } // Try to close the input file if(fclose(inFile) == EOF) { // If file could not be closed, print error fprintf(stderr, "Could not close file: %s\n", argv[IN_FILE]); // Fatal error, exit program exit(1); } // Program finished without errors, return 0 return 0; }
void FunctionEntry::print(ostream& out, int indent) const { out << type()->fullName() << " " << name(); out << "("; int i = 0; const SymTab *st = symTab(); if(st!=NULL) { SymTab::const_iterator it = st->begin(); for (i=0; (it != st->end()); i++, ++it) { SymTabEntry *ste = (SymTabEntry *)(*it); if(ste->kind() == SymTabEntry::Kind::VARIABLE_KIND) { VariableEntry *ve = (VariableEntry *)ste; if(ve->varKind() != VariableEntry::VarKind::PARAM_VAR) { break; } } } } if(i!=0) { printST(out, indent,'\0', '\0', false, 0, i); } out << ")"; if((st != NULL && i < st->size()) || body()) { out << " {"; if(st != NULL && i < st->size()) printST(out, indent,'\0', ';',true, i, st->size()); if(body()) body()->printWithoutBraces(out, indent); out << "}"; } }
void GlobalEntry::print(ostream& out, int indent) const { prtSpace(out, indent); printST(out, indent, '\0', ';', true); prtln(out, indent); const vector<RuleNode*> pr = GlobalEntry::rules(); if(pr.size() == 0 ) prtln(out, indent); for(vector<RuleNode*>::const_iterator it = pr.begin(); it != pr.end(); it++) { (*it)->print(out, indent + STEP_INDENT); endln(out, indent); } prtSpace(out, indent + STEP_INDENT); }
void EventEntry::print(ostream& out, int indent) const { out << "event " << name(); printST(out, indent,'(', ')', false); }
void BlockEntry::print(ostream& out, int indent) const { printST(out, indent, '{', '}', true); }
void check_stmts (tree t) { int typeL, typeR, t_start, t_end; for (; t != NULL; t = t->next) { switch (t->kind) { case Procedure: enterScope(); fprintf (stderr, "Procedure: scope++ : %d\n", scope); handle_decls (t->second); check_stmts (t->third); printST(); exitScope(); fprintf (stderr, "Procedure: scope-- : %d\n", scope); break; case Assign: if ( t->first->kind != LBrac) { // non-array assignment // ST lookup if ( ST[t->first->value]->valid && ST[t->first->value]->scope <= scope) { // entry in ST typeL = ST[t->first->value]->type; typeR = check_expr(t->second); } else { // no visible entry in ST fprintf(stderr, "Entry %d-%s invalid in ST:%d\n", t->first->value, id_name (t->first->value), scope); error_num++; return; } } else if (t->first->kind == LBrac) { // array assignment // ST array lookup if ( ST[t->first->first->value]->valid && ST[t->first->first->value]->type == Array && ST[t->first->first->value]->scope <= scope) { // entry in ST typeL = check_expr (t->first); typeR = check_expr (t->second); } else { // no visible entry in ST fprintf(stderr, "Entry %d-%s invalid in ST:%d\n", t->first->first->value, id_name (t->first->first->value), scope); error_num++; return; } } if (typeL != typeR) { // LHS and RHS of assignment must match type_error(t->kind); return; } break; case If: case Elsif: // expr in If must be Boolean if (check_expr(t->first) != Boolean) { type_error(t->kind); return; } check_stmts(t->second); check_stmts(t->third); break; case Else: check_stmts(t->first); break; case For: // starts a new scope enterScope(); fprintf (stderr, "For: scope++ : %d\n", scope); // 2 range values must be same type t_start = check_expr(t->second->first); t_end = check_expr(t->second->second); if ( t_start != t_end || t_start == NoType) { type_error(t->kind); return; } else { // add Ident to ST w/ type of t_start in a new scope int pos = t->first->value; // Ident in For loop if ( ST[pos]->valid == true) { push (ST[pos]); // push prev scope entry to stack } ST[pos]->index = pos; ST[pos]->type = t_start; ST[pos]->scope = scope; // will be scope not 2 char *tmp = id_name(pos); ST[pos]->name = tmp; ST[pos]->valid = true; ST[pos]->typeSize = -1; ST[pos]->addr = -1; } check_stmts(t->third); // body of For loop printST(); exitScope(); fprintf (stderr, "For: scope-- : %d\n", scope); break; // Exit without bool_expr handled in for loop b/c tree will be NULL case Exit: typeL = check_expr(t->first); if ( typeL != Boolean || typeL == NoType) { type_error( t->kind); } break; case Declare: // starts a new scope enterScope(); fprintf (stderr, "Declare: scope++ : %d\n", scope); handle_decls (t->first); check_stmts (t->second); printST(); exitScope(); fprintf (stderr, "Declare: scope-- : %d\n", scope); break; default: fprintf(stderr, "No stmt match for token %d\n", t->kind); // endScope() } // end switch statement } // end for loop } // end check_stmts()