main() { symtabADT table; scannerADT scanner; string line, name, value; table = NewSymbolTable(); scanner = NewScanner(); SetScannerSpaceOption(scanner, IgnoreSpaces); while (TRUE) { printf("-> "); line = GetLine(); if (StringEqual(line, "quit")) break; SetScannerString(scanner, line); name = ReadToken(scanner); if (MoreTokensExist(scanner)) { if (!StringEqual(ReadToken(scanner), "=")) { Error("Missing equal sign in assignment"); } value = ReadToken(scanner); if (MoreTokensExist(scanner)) { Error("Statement contains additional data"); } Enter(table, name, value); } else { value = Lookup(table, name); if (value == UNDEFINED) { printf("'%s' is undefined.\n", name); } else { printf("%s\n", value); } } } FreeSymbolTable(table); }
/* Parse a generic list (either () or []) */ VyParseTree* ParseListGeneric(int endTokenType){ /* Create a list with no items in it */ VyParseTree* list = MakeListTree(); /* Make sure there is more to read and that the file isn't over */ if(!MoreTokensExist()){ return ParseError("Unclosed list at end of file."); } /* While the list, isn't over add items to it */ VyToken* nextToken; while((nextToken = GetLookAheadToken())->type != endTokenType){ /* Add the next element, which is recieved from Parse(), to the list */ VyParseTree* nextElement = Parse(); AddToList(list, nextElement); /* If there are no more tokens, then a parenthesis is unclosed */ if(!MoreTokensExist()) { VyParseTree* error = ParseError("Unclosed list"); SetPosition(error, nextToken->pos); AddToList(list, error); return list; } } GetNextToken(); return list; }
/* A utility function for parsing a whole file */ VyParseTree* ParseFile(char* filename){ if(filename == NULL){ fprintf(stderr, "Null pointer as filename."); return NULL; } /* Perform lexing */ LexFile(filename); if(GetNumTokens() < 1){ printf("Empty file: %s\n", filename); return NULL; } /* Parse the tokens */ VyParseTree* list = MakeListTree(); while(MoreTokensExist()) { VyParseTree* tree = Parse(); AddToList(list, tree); } CleanLexer(); return list; }
main() { scannerADT myScanner; string token; int nTokens; myScanner = NewScanner(); printf("Enter input line: "); SetScannerString(myScanner, GetLine()); nTokens = 0; while (MoreTokensExist(myScanner)) { token = ReadToken(myScanner); nTokens++; printf("%2d: \"%s\"\n", nTokens, token); } FreeScanner(myScanner); }
/* Parse the next expression */ VyParseTree* Parse(){ /* Check that we have not reached the end of the input stream; if so, return null */ if(!MoreTokensExist()){ return NULL; } /* Get the next token */ VyToken* next = GetNextToken(); /* It's type is used to determine how to continue parsing */ int tokType = next->type; /* Store the result of parsing before returning it */ VyParseTree* expr; /* If it starts with a parenthesis, parse it as a list */ if(tokType == OPAREN){ expr = ParseList(); } /* If it begins with a quote, then parse whatever is next and quote it */ else if(tokType == QUOTE){ expr = ParseQuoted(); } /* Parse a substitution */ else if(tokType == DOLLAR){ expr = ParseSubstitution(); } /* Parse a splicing substitution */ else if(tokType == DOLLARAT){ expr = ParseSpliceSubstitution(); } /* Parse a bracketed list */ else if(tokType == OBRACKET){ expr = ParseBracketedList(); } /* Parse an infix list (curly braces) */ else if(tokType == OCURLY){ expr = ParseCurlyList(); } /* If it is a number, identifier, or string then make a parse tree out of the token */ else if(tokType == IDENT){ VyParseTree* ident = MakeIdent(); SetStrData(ident, next->data); expr = ident; } else if(tokType == NUM){ expr = ParseNumberFromToken(next); } else if(tokType == STRING){ VyParseTree* str = MakeString(); SetStrData(str,next->data); expr = str; } /* Unexpected end of list */ else if(tokType == CPAREN || tokType == CBRACKET || tokType == CCURLY){ VyParseTree* err = ParseError("Unexpected end of list"); SetPosition(err, next->pos); return err; } /* If there is no expression before a :, then the token type will be COLON * Instead of dying, add an error */ else if(tokType == COLON){ VyParseTree* error = ParseError("Reference lacking instance"); SetPosition(error, next->pos); return error; } /* Handle object references: Check whether the next token is a colon. * If so, then use the previously parsed expression (expr) and another * expression gotten from Parse() to create a reference node */ VyToken* lookAhead = GetNextToken(); if(lookAhead != NULL /* Make sure that the token list didn't end before looking at the type */ && lookAhead->type == COLON){ VyParseTree* obj = expr; VyParseTree* ref = Parse(); /* Check for validity */ if(ref == NULL){ expr = Reference(obj, ParseError("Incomplete reference.")); }else{ expr = Reference(obj, ref); } } else{ /* Backtrack one token to make up for the lookahead */ if(lookAhead != NULL) BacktrackToken(); } /* Set the position of the current expression */ SetPosition(expr, next->pos); /* If the tree is an object reference, set the position of * the first part (obj), because it wasn't gotten through a full Parse() call*/ if(expr->type == TREE_REF){ SetPosition(GetObj(expr), next->pos); } return expr; }