Expression *parseExpression( FILE *source, Expression *lvalue )//changed { Token token = scanner(source); Expression *expr; switch(token.type){ case PlusOp: expr = (Expression *)malloc( sizeof(Expression) ); (expr->v).type = PlusNode; (expr->v).val.op = Plus; expr->leftOperand = lvalue; expr->rightOperand = parseValue(source); return parseExpressionTail(source, expr); case MinusOp: expr = (Expression *)malloc( sizeof(Expression) ); (expr->v).type = MinusNode; (expr->v).val.op = Minus; expr->leftOperand = lvalue; expr->rightOperand = parseValue(source); return parseExpressionTail(source, expr); case Alphabet: case PrintOp: ungetstring(token.tok, source); //ungetc(token.tok[0], source); return NULL; case EOFsymbol: return NULL; default: printf("Syntax Error: Expect a numeric value or an identifier %s\n", token.tok); exit(1); } }
Declarations *parseDeclarations( FILE *source )//changed { Token token = scanner(source); Declaration decl; Declarations *decls; switch(token.type){ case FloatDeclaration: case IntegerDeclaration: decl = parseDeclaration(source, token); decls = parseDeclarations(source); return makeDeclarationTree( decl, decls ); case PrintOp: case Alphabet: //ungetc(token.tok[0], source); ungetstring(token.tok,source); return NULL; case EOFsymbol: return NULL; default: printf("Syntax Error: Expect declarations %s\n", token.tok); exit(1); } }
/* * Expand a macro. Called from the cpp mainline routine (via subroutine * macroid()) when a token is found in the symbol table. It calls * expcollect() to parse actual parameters, checking for the correct number. * It then creates a "file" containing a single line containing the * macro with actual parameters inserted appropriately. This is * "pushed back" onto the input stream. (When the get() routine runs * off the end of the macro line, it will dismiss the macro itself.) */ void expand(DEFBUF* tokenp) { int c; FILEINFO* file; #if OSL_DEBUG_LEVEL > 1 if (debug) dumpadef("expand entry", tokenp); #endif /* * If no macro is pending, save the name of this macro * for an eventual error message. */ if (recursion++ == 0) macro = tokenp; else if (recursion == RECURSION_LIMIT) { cerror("Recursive macro definition of \"%s\"", tokenp->name); fprintf(stderr, "(Defined by \"%s\")\n", macro->name); if (rec_recover) { do { c = get(); } while (infile != NULL && infile->fp == NULL); unget(); recursion = 0; return; } } /* * Here's a macro to expand. */ nargs = 0; /* Formals counter */ parmp = parm; /* Setup parm buffer */ switch (tokenp->nargs) { case (-2): /* __LINE__ */ sprintf(work, "%d", line); ungetstring(work); break; case (-3): /* __FILE__ */ for (file = infile; file != NULL; file = file->parent) { if (file->fp != NULL) { sprintf(work, "\"%s\"", (file->progname != NULL) ? file->progname : file->filename); ungetstring(work); break; } } break; default: /* * Nothing funny about this macro. */ if (tokenp->nargs < 0) cfatal("Bug: Illegal __ macro \"%s\"", tokenp->name); while ((c = skipws()) == '\n') /* Look for (, skipping */ wrongline = TRUE; /* spaces and newlines */ if (c != '(') { /* * If the programmer writes * #define foo() ... * ... * foo [no ()] * just write foo to the output stream. */ unget(); cwarn("Macro \"%s\" needs arguments", tokenp->name); fputs(tokenp->name, pCppOut ); return; } else if (expcollect()) /* Collect arguments */ { if (tokenp->nargs != nargs) /* Should be an error? */ { cwarn("Wrong number of macro arguments for \"%s\"", tokenp->name); } #if OSL_DEBUG_LEVEL > 1 if (debug) dumpparm("expand"); #endif } /* Collect arguments */ case DEF_NOARGS: /* No parameters just stuffs */ expstuff(tokenp); /* Do actual parameters */ } /* nargs switch */ }
ReturnCode expand(struct Global *global, DEFBUF *tokenp) { /* * Expand a macro. Called from the cpp mainline routine (via subroutine * macroid()) when a token is found in the symbol table. It calls * expcollect() to parse actual parameters, checking for the correct number. * It then creates a "file" containing a single line containing the * macro with actual parameters inserted appropriately. This is * "pushed back" onto the input stream. (When the get() routine runs * off the end of the macro line, it will dismiss the macro itself.) */ int c; FILEINFO *file; ReturnCode ret=FPP_OK; /* * If no macro is pending, save the name of this macro * for an eventual error message. */ if (global->recursion++ == 0) global->macro = tokenp; else if (global->recursion == RECURSION_LIMIT) { cerror(global, ERROR_RECURSIVE_MACRO, tokenp->name, global->macro->name); if (global->rec_recover) { do { c = get(global); } while (global->infile != NULL && global->infile->fp == NULL); unget(global); global->recursion = 0; return(FPP_OK); } } /* * Here's a macro to expand. */ global->nargs = 0; /* Formals counter */ global->parmp = global->parm; /* Setup parm buffer */ switch (tokenp->nargs) { case (-2): /* __LINE__ */ if(global->infile->fp) /* This is a file */ sprintf(global->work, "%d", global->line); else /* This is a macro! Find out the file line number! */ for (file = global->infile; file != NULL; file = file->parent) { if (file->fp != NULL) { sprintf(global->work, "%d", file->line); break; } } ret=ungetstring(global, global->work); if(ret) return(ret); break; case (-3): /* __FILE__ */ for (file = global->infile; file != NULL; file = file->parent) { if (file->fp != NULL) { sprintf(global->work, "\"%s\"", (file->progname != NULL) ? file->progname : file->filename); ret=ungetstring(global, global->work); if(ret) return(ret); break; } } break; case (-4): /* __FUNC__ */ sprintf(global->work, "\"%s\"", global->functionname[0]? global->functionname : "<unknown function>"); ret=ungetstring(global, global->work); if(ret) return(ret); break; case (-5): /* __FUNC_LINE__ */ sprintf(global->work, "%d", global->funcline); ret=ungetstring(global, global->work); if(ret) return(ret); break; default: /* * Nothing funny about this macro. */ if (tokenp->nargs < 0) { cfatal(global, FATAL_ILLEGAL_MACRO, tokenp->name); return(FPP_ILLEGAL_MACRO); } while ((c = skipws(global)) == '\n') /* Look for (, skipping */ global->wrongline = TRUE; /* spaces and newlines */ if (c != '(') { /* * If the programmer writes * #define foo() ... * ... * foo [no ()] * just write foo to the output stream. */ unget(global); cwarn(global, WARN_MACRO_NEEDS_ARGUMENTS, tokenp->name); /* fputs(tokenp->name, stdout); */ Putstring(global, tokenp->name); return(FPP_OK); } else if (!(ret=expcollect(global))) { /* Collect arguments */ if (tokenp->nargs != global->nargs) { /* Should be an error? */ cwarn(global, WARN_WRONG_NUMBER_ARGUMENTS, tokenp->name); } } else { /* Collect arguments */ return(ret); /* We failed in argument colleting! */ } case DEF_NOARGS: /* No parameters just stuffs */ ret=expstuff(global, tokenp->name, tokenp->repl); /* expand macro */ } /* nargs switch */ return(ret); }