Node * Parser::parseRest() { // TODO: write code for parsing rest //Token * NextToken; //NextToken = scanner->getNextToken(); LookAheadToken = scanner->getNextToken(); LookAhead = true; if(LookAheadToken->getType() == RPAREN) { return new Nil(); }else if(LookAheadToken->getType() == DOT) { Node * DotNode; LookAhead = scanner->getNextToken(); DotNode = parseExp(); LookAhead = scanner->getNextToken(); if(LookAheadToken->getType() != RPAREN) { cerr << "Parse Error: Expecting Expression following dot\n"; LookAheadToken = NULL; } return DotNode; }else { //what about the lookahead token (NextToken)? It needs to be //put back before we return? return new Cons(parseExp(), parseRest()); } return NULL; }
Node * Parser::parseRest() { // TODO: write code for parsing rest Token * NextTok = scanner->getNextToken(); if(NextTok->getType() == RPAREN) { //cout << "parseRest() found RPAREN\n"; return new Nil(); } else if(NextTok->getType() == DOT) { Node * DotNode; NextTok = scanner->getNextToken(); LookAheadToken = NextTok; DotNode = parseExp(); NextTok = scanner->getNextToken(); if(NextTok->getType() != RPAREN) { cerr << "Parse Error: Expecting Expression following dot\n"; //LookAheadToken = NULL; } return DotNode; } else { //what about the lookahead token (NextToken)? It needs to be //put back before we return? //cout << "parseRest() setting LookAheadToken = NextTok\n"; LookAheadToken = NextTok; //cout << "parseRest() building a Cons(parseExp, parseRest)\n"; return new Cons(parseExp(), parseRest()); } return NULL; }
ExpPtr parseFor (Lexer& lex) { Span spStart, spEnd; ExpPtr val1, val2, body; spStart = lex.eat(tFor).span; auto var = lex.eat(tIdent).str; lex.eat(tColon); val1 = parseExp(lex); if (lex.current() == tArrow) { lex.advance(); val2 = parseExp(lex); } else val2 = nullptr; body = parseBlock(lex); spEnd = body->span; if (val2 == nullptr) return Exp::make(eForEach, var, { val1, body }, spStart + spEnd); else return Exp::make(eForRange, var, { val1, val2, body }, spStart + spEnd); }
ExpPtr parseCond (Lexer& lex) { Span spStart, spEnd; ExpPtr expCond, expThen, expElse; bool blockRequired = true; spStart = lex.eat(tIf).span; expCond = parseExp(lex); if (lex.current() == tThen) { lex.advance(); blockRequired = false; } expThen = blockRequired ? parseBlock(lex) : parseExp(lex); if (lex.current() == tElse) { lex.advance(); if (blockRequired) { // if {} else {} // if {} else if ... if (lex.current() != tIf) lex.expect(tLCurl); expElse = parseExp(lex); } else expElse = parseExp(lex); spEnd = expElse->span; } else if (!blockRequired) lex.expect(tElse); else { auto expUnit = Exp::make(eTuple, {}, spStart); expThen->subexps.push_back(expUnit); expElse = expUnit; // no else => unit (zero tuple) spEnd = expThen->span; } return Exp::make(eCond, { expCond, expThen, expElse }, spStart + spEnd); }
bool isNumber(const char *s) { // empty space // +/- // [0123456789] // . // [0123456789] // e/E // [0123456789] // empty space // empty string should be treated as false? if (s == nullptr || *s == 0) return false; // process empty space parseSpace(s); if (*s == 0) return false; // empty string parseSign(s); if (*s == 0) return false; if (parseDigit(s) == 0) { if (!parseDot(s)) return false; if (parseDigit(s) == 0) return false; if (parseSpace(s) > 0) return *s == 0; if (*s == 0) return true; if (!parseExp(s)) return false; parseSign(s); if (parseDigit(s) == 0) return false; parseSpace(s); return *s == 0; } else { if (parseSpace(s) > 0) return *s == 0; if (*s == 0) return true; if (parseDot(s)) { parseDigit(s); if (parseSpace(s) > 0) return *s == 0; if (*s == 0) return true; if (!parseExp(s)) return false; parseSign(s); if (parseDigit(s) == 0) return false; parseSpace(s); return *s == 0; } else if (parseExp(s)) { parseSign(s); if (parseDigit(s) == 0) return false; parseSpace(s); return *s == 0; } else { return false; } } }
void parseBlockExp (Lexer& lex, ExpList& list) { switch (lex.current().tok) { case tSemicolon: lex.advance(); break; case tLet: list.push_back(parseLet(lex)); lex.eat(tSemicolon); break; case tLCurl: list.push_back(parseBlock(lex)); break; case tIf: list.push_back(parseCond(lex)); break; case tLoop: list.push_back(parseLoop(lex)); break; case tFor: list.push_back(parseFor(lex)); break; // everthing else does default: list.push_back(parseAssign(lex, parseExp(lex))); if (lex.current() != tSemicolon) lex.expect(tRCurl); else lex.eat(tSemicolon); break; } }
ExpPtr parseLambda (Lexer& lex) { Span spStart, spEnd; SigPtr sig; ExpPtr body; spStart = lex.current().span; if (lex.current() == tFunc) { lex.advance(); sig = parseSigParens(lex); body = parseBlock(lex); } else { lex.eat(tLambda); sig = parseSig(lex, true); lex.eat(tArrow); body = parseExp(lex); } spEnd = body->span; return Exp::make(eLambda, sig->toSigType(), "", { body }, spStart + spEnd); }
struct keyExp *keyExpParse(char *text) /* Parse text into key expression. Squawk and die if it * fails. */ { struct keyExp *ke; struct kxTok *tok; AllocVar(ke); ke->tokenList = tok = kxTokenize(text, TRUE); ke->rootExp = parseExp(tok); return ke; }
ExpPtr parseAssign (Lexer& lex, ExpPtr left) { if (lex.current() != tEqual) return left; lex.eat(tEqual); auto right = parseExp(lex); lex.expect(tSemicolon); return Exp::make(eAssign, { left, right }, left->span + right->span); }
ExpPtr parseLet (Lexer& lex) { Span spStart, spEnd; std::string name; TyPtr ty; ExpPtr init; // 'let' <var> '=' <exp> ';' spStart = lex.eat(tLet).span; parseVar(lex, name, ty, spEnd); lex.eat(tEqual); init = parseExp(lex); spEnd = init->span; auto e = Exp::make(eLet, ty, name, { init }, spStart + spEnd); return e; }
int main(int argc, char const *argv[]) { std::fstream f; f.open(argv[1], std::fstream::in); std::map<identifier,Expression> values; for (std::string line; std::getline(f, line);) parseExp(values, line); // the below is needed for part 2 valtype part1 = 956; values["b"] = {Expression::Operation::EQ,{part1}}; std::cout << "a <-" << evaluate(values,"a") << std::endl; return 0; }
ExpPtr parseList (Lexer& lex) { Span spStart, spEnd; ExpList vals; spStart = lex.eat(tLBrack).span; while (lex.current() != tRBrack) { vals.push_back(parseExp(lex)); if (lex.current() == tComma) lex.advance(); else break; } spEnd = lex.eat(tRBrack).span; return Exp::make(eList, std::move(vals), spStart + spEnd); }
ExpPtr parseLoop (Lexer& lex) { Span spStart, spEnd; ExpPtr body; spStart = lex.eat(tLoop).span; ExpList sub; sub.reserve(2); if (lex.current() == tLCurl) { sub.push_back(body = parseBlock(lex)); } else { sub.push_back(parseExp(lex)); sub.push_back(body = parseBlock(lex)); } spEnd = body->span; return Exp::make(eLoop, std::move(sub), spStart + spEnd); }
ExpPtr parseTuple (Lexer& lex) { ExpList exps; ExpPtr e; Span spStart, spEnd; spStart = lex.eat(tLParen).span; while (lex.current() != tRParen) { e = parseExp(lex); exps.push_back(e); if (lex.current() == tComma) lex.advance(); else break; } spEnd = lex.eat(tRParen).span; return Exp::make(eTuple, exps, spStart + spEnd); }
void GenBench(sParams* PBBench) { boolean finished = FALSE; int32 prevExp = 0; int32 currExp; int32 numExp; FILE* fp = NULL; // file pointer FILE* fp2 = NULL; // file pointer char str[MAX_STR]; int32 tabVal[MAX_VARYING_VAL]; sParams PBExp; int32 nbVal; item* memList; bool tabSel[MAXBENCH*MAXMODE]; int32 nbExp = 0; int32 key = 0; parseSel(PBBench, tabSel); // Allocate data structure for computing target offset memList = InitMemList((int32)(PBBench->deviceSize)); fp2 = fopen(PBBench->outName, "w"); if (fp2 == NULL) HandleError("GenBench", "Could not open output file", GetLastError(), ERR_ABORT); while (finished == FALSE) { // find the next experiment - it is the smallest numExp, greater than prevExp if ((fp = fopen(PBBench->expPlan, "r")) == NULL ) HandleError("GenBench", "Cannot open experimentation plan file", GetLastError(), ERR_ABORT); currExp = INT32_MAX; while (fgets(str, MAX_STR,fp) != NULL) { numExp = atoi(str); if ((numExp > prevExp) && (numExp < currExp)) { currExp = numExp; } } if ((currExp > prevExp) && (currExp != INT32_MAX)) { printf("=================== Order Number %d\n", currExp); //New param structure InitParams(&PBExp); PBExp.deviceNum = PBBench->deviceNum; PBExp.IOSize = PBBench->IOSize; PBExp.IOCount = PBBench->IOCount; PBExp.IOCountSR = PBBench->IOCountSR; PBExp.IOCountRR = PBBench->IOCountRR; PBExp.IOCountSW = PBBench->IOCountSW; PBExp.IOCountRW = PBBench->IOCountRW; PBExp.ignoreIO = PBBench->ignoreIO; PBExp.ignoreIOSR = PBBench->ignoreIOSR; PBExp.ignoreIORR = PBBench->ignoreIORR; PBExp.ignoreIOSW = PBBench->ignoreIOSW; PBExp.ignoreIORW = PBBench->ignoreIORW; PBExp.collectErase = PBBench->collectErase; PBExp.pauseExp = PBBench->pauseExp; PBExp.fake = PBBench->fake; PBExp.bufferType = PBBench->bufferType; PBExp.deviceSize = PBBench->deviceSize; PBExp.burstIO = PBBench->burstIO; PBExp.nbRun = PBBench->nbRun; // parse the experiment nbVal = parseExp(fp, currExp, &PBExp, tabVal); if (tabSel[(PBExp.microBenchID - 1) * MAXMODE + PBExp.expID - 1] == TRUE) { for (int32 exp = 0; exp < nbVal; ++exp) { // Compute the different parameters if (PBExp.microBenchID == PAR) { for (PBExp.runID = 0; PBExp.runID < PBExp.nbRun; (PBExp.runID)++) { PBExp.parDeg = tabVal[exp]; for (int32 pID = 0; pID < PBExp.parDeg; ++pID) { PBExp.processID = PBExp.parDeg - pID - 1; PBExp.key = key++; ComputeParams(&PBExp, memList,PBExp.parDeg, nbVal ); GenExp(fp2, &PBExp); nbExp++; PBExp.IOSize = PBBench->IOSize; PBExp.IOCount = PBBench->IOCount; PBExp.ignoreIO = PBBench->ignoreIO; } } } else { for (PBExp.runID = 0; PBExp.runID < PBExp.nbRun; (PBExp.runID)++) { PBExp.key = key++; ComputeParams(&PBExp, memList, tabVal[exp], nbVal); GenExp(fp2, &PBExp); nbExp ++; PBExp.IOSize = PBBench->IOSize; PBExp.IOCount = PBBench->IOCount; PBExp.ignoreIO = PBBench->ignoreIO; } } } } else printf("=================== Not Selected\n"); fprintf(fp2, "\n"); } else finished = TRUE; prevExp = currExp; if (fp) fclose(fp); } fclose(fp2); // close the output file if we opened it while (memList) { item *tmp = memList->next; free(memList); memList = tmp; } sprintf(str, "%d Experiments have been generated\n", nbExp); OutputString(OUT_LOG, str); }
Node * Parser::parseExp() { // TODO: write code for parsing an exp Token * t = scanner->getNextToken(); if (! LookAhead) //if the lookahead token hasn't been read... { LookAheadToken = t;//...make t the "lookahead"! } if(LookAheadToken == NULL) //We don't have a LookAheadToken { Token * NextTok = scanner->getNextToken(); //we can check the TokenType of the NextTok in 2 ways... which //do you prefer? //1st way? TokenType NextTokType = NextTok->getType(); if(NextTokType == LPAREN) { return parseRest(); }else if(NextTok->getType() == QUOTE) //2nd way? { Cons * NewConsNode; NewConsNode = new Cons(parseExp(), new Nil()); return new Cons(new Ident("quote"), NewConsNode); }else if(NextTok->getType() == FALSET) { return new BoolLit(false); }else if(NextTok->getType() == TRUET) { return new BoolLit(true); }else if(NextTok->getType() == INT) { return new IntLit(NextTok->getIntVal()); }else if(NextTok->getType() == STRING) { return new StrLit(NextTok->getStrVal()); }else if(NextTok->getType() == IDENT) { return new Ident(NextTok->getName()); }else { cerr << "Parse Error: Unexpected Toke\n"; return parseExp(); } }else //We have the LookAheadToken already { if(LookAheadToken->getType() == LPAREN) { return parseRest(); } else if(LookAheadToken->getType() == QUOTE) { ///??? Cliff, does this look right? -not sure...I'm a little ///fuzzy on the whole Cons phenomenon LookAheadToken = NULL; //don't want LookAhead in next parseExp Cons * NewConsNode; NewConsNode = new Cons(parseExp(), new Nil()); return new Cons(new Ident("quote"), NewConsNode); } else if (LookAheadToken->getType() == FALSET) { return new BoolLit(false); } else if (LookAheadToken->getType() == TRUET) { return new BoolLit(true); } else if (LookAheadToken->getType() == INT) { return new IntLit(LookAheadToken->getIntVal()); } else if (LookAheadToken->getType() == STRING) { return new StrLit(LookAheadToken->getStrVal()); } else if (LookAheadToken->getType() == IDENT) { return new Ident(LookAheadToken->getName()); } else //I don't know if we need this, and it's giving me an error //message for stuff that shouldn't be an erroR, so I'm taking it //out for now { cerr << "\nWarning : Invalid expression"; //need to continue parsing LookAheadToken = NULL; return parseExp(); } } return NULL; }
void GenBench (UflipParams *PBBench) { bool finished = false; int32_t prevExp = 0; int32_t currExp; int32_t numExp; FILE *fp = NULL; /* file pointer */ FILE *fp2 = NULL; /* file pointer */ char str [MAX_STR]; int32_t tabVal [MAX_VARYING_VAL]; UflipParams *PBExp; int32_t nbVal; item *memList; bool tabSel [MAXBENCH*MAXMODE]; int32_t nbExp = 0; int key = 0; if (parseSel (PBBench, tabSel) == -1) HandleError (__func__, "Problem with the experimentation plan!", 0, ERR_ABORT); /* Allocate data structure for computing target offset */ memList = InitMemList ((int32_t) (PBBench->deviceSize)); if (memList == NULL) HandleError (__func__, "Could not allocate memList", errno, ERR_ABORT); fp2 = fopen (PBBench->outName, "w"); if (fp2 == NULL) HandleError (__func__, "Could not open output file", errno, ERR_ABORT); if (fwrite (SCRIPT_SHEBANGS, sizeof (char), strlen (SCRIPT_SHEBANGS), fp2) < strlen (SCRIPT_SHEBANGS)) { int err = errno; fclose (fp2); HandleError (__func__, "Could not write to output file", err, ERR_ABORT); } while (finished == false) { /* find the next experiment - it is the smallest numExp, greater than prevExp */ if ((fp = fopen (PBBench->expPlan, "r")) == NULL ) HandleError (__func__, "Cannot open experimentation plan file", errno, ERR_ABORT); currExp = INT32_MAX; while (fgets(str, MAX_STR,fp) != NULL) { numExp = atoi (str); if ((numExp > prevExp) && (numExp < currExp)) currExp = numExp; } if ((currExp > prevExp) && (currExp != INT32_MAX)) { printf ("=================== Order Number %d\n", currExp); /* New param structure */ PBExp = uflip_params_new (); PBExp->device = uflip_device_copy (PBBench->device); if (PBExp->device == NULL) HandleError (__func__, "couldn't allocate Param->device subblock", 0, ERR_ABORT); InitParams (PBExp); PBExp->IOSize = PBBench->IOSize; PBExp->IOCount = PBBench->IOCount; PBExp->IOCountSR = PBBench->IOCountSR; PBExp->IOCountRR = PBBench->IOCountRR; PBExp->IOCountSW = PBBench->IOCountSW; PBExp->IOCountRW = PBBench->IOCountRW; PBExp->ignoreIO = PBBench->ignoreIO; PBExp->ignoreIOSR = PBBench->ignoreIOSR; PBExp->ignoreIORR = PBBench->ignoreIORR; PBExp->ignoreIOSW = PBBench->ignoreIOSW; PBExp->ignoreIORW = PBBench->ignoreIORW; PBExp->collectErase = PBBench->collectErase; PBExp->pauseExp = PBBench->pauseExp; PBExp->fake = PBBench->fake; PBExp->bufferType = PBBench->bufferType; PBExp->deviceSize = PBBench->deviceSize; PBExp->burstIO = PBBench->burstIO; PBExp->nbRun = PBBench->nbRun; /* parse the experiment */ nbVal = parseExp (fp, currExp, PBExp, tabVal); if (nbVal == -1) HandleError (__func__, "Problem with the experimentation selection!", 0, ERR_ABORT); if (tabSel [(PBExp->microBenchID - 1) * MAXMODE + PBExp->expID - 1] == true) { for (int32_t exp = 0; exp < nbVal; ++exp) { /* Compute the different parameters */ if (PBExp->microBenchID == PAR) { for (PBExp->runID = 0; PBExp->runID < PBExp->nbRun; ++PBExp->runID) { PBExp->parDeg = tabVal [exp]; for (int32_t pID = 0; pID < PBExp->parDeg; ++pID) { PBExp->processID = PBExp->parDeg - pID - 1; PBExp->key = key++; ComputeParams (PBExp, memList, PBExp->parDeg, nbVal); GenExp (fp2, PBExp); ++nbExp; PBExp->IOSize = PBBench->IOSize; PBExp->IOCount = PBBench->IOCount; PBExp->ignoreIO = PBBench->ignoreIO; } } } else { for (PBExp->runID = 0; PBExp->runID < PBExp->nbRun; ++PBExp->runID) { PBExp->key = key++; ComputeParams (PBExp, memList, tabVal [exp], nbVal); GenExp (fp2, PBExp); ++nbExp; PBExp->IOSize = PBBench->IOSize; PBExp->IOCount = PBBench->IOCount; PBExp->ignoreIO = PBBench->ignoreIO; } } } } else { printf ("=================== Not Selected\n"); } fprintf (fp2, "\n"); } else { finished = true; } prevExp = currExp; uflip_params_destroy (PBExp); PBExp = NULL; if (fp) fclose (fp); } fclose (fp2); while (memList) { item *tmp = memList->next; free (memList); memList = tmp; } sprintf (str, "%d Experiments have been generated\n", nbExp); OutputString (OUT_LOG, str); }