/* Function: sqrtFunction() * Usage: is called by formulaStringScanning() function if it detect sqrt token in formula * -----------------------------------------------------------------------------------------// * Library sqrt function execution. Expects for brackets and involves * formulaStringScanning process for expression in brackets. Return sqrt function result * for obtained value in brackets. * * @param scanner TokenScanner for user formula * @param xValue Value for x variable in user equation */ double sqrtFunction(TokenScanner& scanner, double xValue) { bool sqrtFail = false; string token = ""; double num1 = 0; if(scanner.hasMoreTokens()) { token = scanner.nextToken(); if(token == "(") { //waiting for brackets at this place bool bracketsOpened = true; /* Calls internal formulaStringScanning process for expression in brackets */ num1 = formulaStringScanning(scanner, bracketsOpened, xValue); } else { sqrtFail = true; } } if(sqrtFail) { cout << " - SQRT FUNCTION FAULT" << endl; failFlag = true; return 0; } /* Returns sqrt function result */ return sqrt(num1); }
/* Function: sqrtFunction() * ------------------------- * Library sqrt function execution. Expects for brackets and involves * formulaStringScanning process for expression in brackets. Return sqrt function result * for obtained value in brackets. * * @param scanner TokenScanner for user formula */ double sqrtFunction(TokenScanner& scanner) { bool sqrtFailFlag = false; string token = ""; double sqrtParam = 0; if (scanner.hasMoreTokens()) { token = scanner.nextToken();//waiting for brackets at this place if (token == "(") { bool bracketsOpened = true; /* Calls internal scanFormulaString process for expression in brackets */ sqrtParam = scanFormulaString(scanner, bracketsOpened); } else { sqrtFailFlag = true; } } if (sqrtFailFlag) { cout << " - SQRT FUNCTION FAULT" << endl; FAIL_FLAG = true; return 0; } /* Returns sqrt function result */ return sqrt(sqrtParam); }
/** * Receive information from file, processes and displays the result on the screen. */ void processText(TokenScanner & scanner){ int counterSentences = 0; int counterWords = 0; int counterSyllable = 0; double grade = 0.0; scanner.ignoreWhitespace(); // ignores spaces scanner.addWordCharacters("'"); // does part of the token is the character "'" // processes each token while (scanner.hasMoreTokens()){ string token = scanner.nextToken(); counterSentences += checkSentences(token); if(checkWords(token)){ counterWords ++; counterSyllable += colSyllable(token); } } // If the file does not contain any words or sentences, assume that their one if(counterWords == 0 || counterSentences == 0) counterSentences = counterWords = 1; grade = getGrade(counterSentences, counterWords, counterSyllable); cout << "Words : " << counterWords << endl; cout << "Syllable : " << counterSyllable << endl; cout << "Sentences : " << counterSentences << endl; cout << "Grade : " << grade << endl; }
bool isHaiku(string filename) { fstream infile; infile.open(filename.c_str()); string temp; int count = 0; TokenScanner scanner; while(getline(infile, temp)){ count++; int syllables = 0; scanner.setInput(temp); while (scanner.hasMoreTokens()){ syllables += syllablesIn(scanner.nextToken()); } if((count == 1 || count ==3)&&syllables!=5){ infile.close(); return false; } if (count == 2 && syllables !=7){ infile.close(); return false; } if (count >3){ infile.close(); return false; } } return true; }
LetStmt::LetStmt(TokenScanner &scanner) { identifier = scanner.nextToken(); op = scanner.nextToken(); exp = readE(scanner, 0); if (scanner.hasMoreTokens()) { error("Extraneous token " + scanner.nextToken()); } }
/* * Implementation notes: the InputStmt subclass * ---------------------------------------------- * Instances of this class read the identifier from the scanner and notify * the user if its format is illegal. In the execute method, it records * the input of the user as the value of the identifier in "state". */ InputStmt::InputStmt(TokenScanner & scanner){ string nextToken = scanner.nextToken(); if (isdigit(nextToken[0])) error("Invalid identifier for Input Statement -- can't start with an integer."); if (scanner.hasMoreTokens()) error("Unexpected token: " + scanner.nextToken()); identifier = nextToken; }
/* Function: scanCPlusPlusTokens() * Sets scanner features. */ void scanCPlusPlusTokens(TokenScanner & scanner) { scanner.ignoreWhitespace(); /* Return numbers */ scanner.scanNumbers(); scanner.addOperator("%"); scanner.addOperator("/"); scanner.addOperator("*"); scanner.addOperator("("); scanner.addOperator(")"); }
/* * Function: listProgram * Usage: listProgram(program, scanner); * ------------------------------------------- * Displays the lines of the program. It calls either version of program.toString() * depending on whether the user specifies line numbers. */ void listProgram(Program & program, TokenScanner & scanner) { if (!scanner.hasMoreTokens()) { program.toString(); } else { int startLine = stringToInteger(scanner.nextToken()); scanner.nextToken(); int endLine = stringToInteger(scanner.nextToken()); program.toString(startLine, endLine); } }
IfStmt::IfStmt(TokenScanner &scanner) { lhs = readE(scanner, 0); op = scanner.nextToken(); rhs = readE(scanner, 0); if (scanner.nextToken() != "THEN") { error("Syntax error! Invalid IF statement!"); } nextLine = stringToInteger(scanner.nextToken()); if (scanner.hasMoreTokens()) { error("Extraneous token " + scanner.nextToken()); } }
/* * Implementation notes: the LetStmt subclass * ---------------------------------------------- * Instances of this class have an identifier and an expression that follow * the lines with the LET keyword. If no such elements are found, an error * is thrown. */ LetStmt::LetStmt(TokenScanner & scanner) { string nextToken = scanner.nextToken(); //Checks that the identifier is alphanumeric for (int i = 0; i < nextToken.length(); i++) { char ch = nextToken[i]; if (!isalnum(ch)) error("Identifier for the LET command must be alphanumeric."); } identifier = nextToken; nextToken = scanner.nextToken(); if (nextToken != "=") error("Invalid expression for the LET command."); exp = parseExp(scanner); }
static bool isFormula(string& mainFormula, string& formula, string& cellname1, string& cellname2, TokenScanner& scanner, SSModel& cellsheet) { if (cellsheet.isFormula(formula)) { cellname1 = toUpperCase(scanner.nextToken()); mainFormula += cellname1 + scanner.nextToken(); cellname2 = toUpperCase(scanner.nextToken()); if (checkRange(cellname1,cellname2, cellsheet)) { string bracket = scanner.nextToken(); if (bracket == ")") { mainFormula += cellname2 + bracket; return true; } } } return false; }
/* * Implementation notes: the GotoStmt subclass * ---------------------------------------------- * Instances of this class redirect the program's execution to the line number * specified by the user. If such line doesn't exist, the user is notified. */ GotoStmt::GotoStmt(TokenScanner & scanner, Program & program){ string nextToken = scanner.nextToken(); for (int i = 0; i < nextToken.length(); i++) { if(!isdigit(nextToken[i])) error("Illegal argument for the GOTO command."); } int num = stringToInteger(nextToken); line = num; }
void processLine(string line, Program & program, EvalState & state) { TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); string str=scanner.nextToken(); if (scanner.getTokenType(str)==NUMBER) { int lineNumber=stringToInteger(str); string token=scanner.nextToken(); scanner.saveToken(token); if (token!="") { program.addSourceLine(lineNumber, line); program.setParsedStatement(lineNumber, parseStatement(scanner)); } else { program.removeSourceLine(lineNumber); } } else if (str=="LIST") { for (int i=program.getFirstLineNumber(); i!=-1; i=program.getNextLineNumber(i)) { cout << program.getSourceLine(i)<<endl; } } else if (str=="CLEAR") { program.clear(); } else if(str=="QUIT") exit(0); else if (str=="HELP") cout<<"This is a minimal BASIC interpreter."<<endl; else if (str=="RUN") { int currentLine=program.getFirstLineNumber(); state.setCurrentLine(currentLine); while (currentLine!=-1) { program.getParsedStatement(currentLine)->execute(state); if(currentLine!=state.getCurrentLine()) { currentLine=state.getCurrentLine(); } else { currentLine=program.getNextLineNumber(currentLine); state.setCurrentLine(currentLine); } } } }
/* Function: powFunction() * Usage: is called by formulaStringScanning() function if it detect pow token in formula * -----------------------------------------------------------------------------------------// * Library pow function execution. Believe that it's normalized function - * without any variables like "x" or "y" - just pow(<value>, <power for value>): * pow(2, 4) = 16 * Expects brackets, and return pow function result for values in brackets. * * @param scanner TokenScanner for user formula */ double powFunction(TokenScanner& scanner) { bool powFail = false; string token = ""; string num1 = ""; string num2 = ""; while(scanner.hasMoreTokens()) { token = scanner.nextToken();//waiting for brackets at this place if(token == "(") { num1 = scanner.nextToken();//pow function param1 token = scanner.nextToken();//waiting coma at this place if(token == ",") { num2 = scanner.nextToken();//pow function param2 token = scanner.nextToken();//waiting for brackets at this place if(token == ")") { break; } else { powFail = true; } } else { powFail = true; } } else { powFail = true; } if(powFail) { cout << " - POW FUNCTION INPUT FAULT!" << endl; failFlag = true; return 0; } } /* Returns pow function result */ return pow(stringToDouble(num1), stringToDouble(num2)); }
void processLine(string line, Program & program, EvalState & state) { TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); // Expression *exp = parseExp(scanner); // int value = exp->eval(state); // cout << value << endl; // delete exp; if (!scanner.hasMoreTokens()) { return; } string firstToken = toUpperCase(scanner.nextToken()); if (firstToken == "RUN") { runProgram(program, state); } else if (firstToken == "QUIT") { exit(0); } else if (firstToken == "HELP") { dspHelp(); } else if (firstToken == "CLEAR") { program.clear(); } else if (firstToken == "LIST") { listCmd(program); } else if (firstToken == "INPUT" || firstToken == "PRINT" || firstToken == "LET") { scanner.saveToken(firstToken); Statement * stmt = parseStatement(scanner); stmt->execute(state); delete stmt; } else { int lineNumber = stringToInteger(firstToken); if (!scanner.hasMoreTokens()) { program.removeSourceLine(lineNumber); } else { int length = firstToken.length(); string source = line.substr(length); program.addSourceLine(lineNumber, source); Statement * stmt = parseStatement(scanner); program.setParsedStatement(lineNumber, stmt); } } }
/* * Implementation notes: the IfStmt subclass * ---------------------------------------------- * Instances of this class check if the expression that follows "IF" is true. * If it is, the program goes to the line indicated; if not, the program continues * to the next line. */ IfStmt::IfStmt(TokenScanner & scanner, Program & program){ string lhs = ""; string nextToken = scanner.nextToken(); while (nextToken != "=" && nextToken != ">" && nextToken != "<" && nextToken != "") { lhs += nextToken; nextToken = scanner.nextToken(); } if (!(nextToken == "=" || nextToken == ">" || nextToken == "<")) error("Illegal operator for IF command"); op = nextToken; nextToken = scanner.nextToken(); string rhs = ""; while (nextToken != "THEN" && nextToken != "then" && nextToken != "") { rhs += nextToken; nextToken = scanner.nextToken(); } if (nextToken != "THEN" && nextToken != "then") error("Incorrect argument for IF command."); //scanner for the lhs expression TokenScanner scanner2; scanner2.ignoreWhitespace(); scanner2.scanNumbers(); scanner2.setInput(lhs); lhsExp = parseExp(scanner2); //scanner for the rhs expression TokenScanner scanner3; scanner3.ignoreWhitespace(); scanner3.scanNumbers(); scanner3.setInput(rhs); rhsExp = parseExp(scanner3); lineNumber = stringToInteger(scanner.nextToken()); //CHECK FOR ERRORS HERE }
void toAlpha(std::string word, Map<std::string, std::string>& symbolTable) { TokenScanner scanner; scanner.ignoreWhitespace(); for(char i = 'A'; i < 'Z'; i++) scanner.addWordCharacters(symbolTable.get(charToString(i))); scanner.setInput(word); while(scanner.hasMoreTokens()) { std::string symbol = scanner.nextToken(); cout << symbolTable.get(symbol); } cout << endl; }
void interpreter(void) { std::string line; TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); Map<std::string, std::string> symbolTable; cout << "Interpreter is running: " << endl; // Main loop: std::string key, value; while(true) { cout << "> "; line = getLine(); if(line == "quit") break; else if(line == "list") { for(std::string key : symbolTable) { cout << key << " = " << symbolTable.get(key) << endl; } } else if(symbolTable.containsKey(line)) cout << symbolTable.get(line) << endl; // Parse statements: else { scanner.setInput(line); bool isValue = false; while(scanner.hasMoreTokens()) { std::string token = scanner.nextToken(); if(isValue) value = token; else if(token == "=") isValue = true; else key = token; } symbolTable.add(key, value); } } cout << "Interpreter is stopped." << endl; }
void processLine(string line, Program & program, EvaluationContext & context) { TokenScanner scanner; scanner.ignoreWhitespace(); scanner.setInput(line); string firstToken = toUpperCase(scanner.nextToken()); if (firstToken == "RUN") { runProgram(program, context); } else if (firstToken == "LIST") { listProgram(program, scanner); } else if (firstToken == "CLEAR") { program.clear(); } else if (firstToken == "HELP") { if (!scanner.hasMoreTokens()) { displayHelp(); } else { specificHelp(scanner); } } else if (firstToken == "QUIT") { exit(0); } else { int lineNumber = stringToInteger(firstToken); if (!scanner.hasMoreTokens()) { program.removeSourceLine(lineNumber); } else { Statement *stmt = parseStatement(scanner); program.addSourceLine(lineNumber, line); program.setParsedStatement(lineNumber, stmt); } } }
/* Function: powFunction() * ------------------------ * Library pow function execution. Expects sequentally: * - brackets, param1, coma, param2, brackets. * * @param scanner TokenScanner for user formula */ double powFunction(TokenScanner& scanner) { bool powFailFlag = false; string token = ""; string powParam_1 = ""; //pow function param1 string powParam_2 = ""; //pow function param2 while (scanner.hasMoreTokens()) { token = scanner.nextToken();//waiting for brackets at this place if (token == "(") { powParam_1 = scanner.nextToken(); token = scanner.nextToken();//waiting for coma at this place if (token == ",") { powParam_2 = scanner.nextToken(); token = scanner.nextToken();//waiting for brackets - end of pow params input if (token == ")") { break; } else { powFailFlag = true; } } else { powFailFlag = true; } } else { powFailFlag = true; } if (powFailFlag) { cout << " - POW FUNCTION INPUT FAULT!" << endl; FAIL_FLAG = true; return 0; } } /* Returns pow function result */ double param1 = stringToDouble(powParam_1); double param2 = stringToDouble(powParam_2); return pow(param1, param2); }
/* * Implementation notes: the PrintStmt subclass * ---------------------------------------------- * Instances of this class evaluate the expression that is passed * to them through the scanner and then print the result using the * excecute method. */ PrintStmt::PrintStmt(TokenScanner & scanner) { exp = readE(scanner, 0); if (scanner.hasMoreTokens()) { error("Extraneous token " + scanner.nextToken()); } }
void processLine(string line, Program & program, EvalState & state) { /* TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); Expression *exp = parseExp(scanner); int value = exp->eval(state); cout << value << endl; delete exp;*/ TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); string token = scanner.nextToken(); TokenType type = scanner.getTokenType(token); if (type == WORD){ if (token == "RUN") { int current_line=program.getFirstLineNumber(); while (current_line>=0) { int next_line = program.getNextLineNumber(current_line); Statement* stat=program.getParsedStatement(current_line); StatementType type = stat->get_type(); if (type == END) break; if (type == GOTO) { ((Gotostmt*)stat)->execute(state,current_line); continue; } if (type == IF) { ((Ifstmt*)stat)->execute(state, current_line); if (current_line != -2) continue; } stat->execute(state); current_line = next_line; } } if (token == "QUIT") { exit(0); } if (token == "CLEAR") { program.clear(); EvalState state1; state = state1; } if (token == "HELP") { } if (token == "LIST") { int current_line = program.getFirstLineNumber(); while (current_line != -1) { cout << program.getSourceLine(current_line) << endl; current_line = program.getNextLineNumber(current_line); } } if (token == "INPUT"){ string st = scanner.nextToken(); if (scanner.hasMoreTokens()) error("SYNTAX ERROR"); Inputstmt inputst(st); inputst.execute(state); } if (token == "PRINT"){ Printstmt printst(scanner); printst.execute(state); } if (token == "LET") { Letstmt lets(scanner); lets.execute(state); } if (token != "RUN"&&token != "CLEAR"&&token != "HELP"&&token != "LIST"&&token != "QUIT"&&token != "PRINT"&&token != "LET"&&token != "INPUT") error("SYNTAX ERROR"); } else if (type == NUMBER){ int line_num = atoi(token.c_str()); string token2 = scanner.nextToken(); if (token2 == "") { program.removeSourceLine(line_num); return; } if (token2 == "REM") { string str, temp; while (scanner.hasMoreTokens()) { temp = scanner.nextToken(); str += temp; } Statement* remst = new Remstmt(str); program.setParsedStatement(line_num, remst); program.addSourceLine(line_num, line); return; } if (token2 == "LET") { Statement *letst = new Letstmt(scanner); program.setParsedStatement(line_num, letst); program.addSourceLine(line_num, line); return; } if (token2 == "PRINT") { Statement *printst = new Printstmt(scanner); program.setParsedStatement(line_num, printst); program.addSourceLine(line_num, line); return; } if (token2 == "INPUT") { string st = scanner.nextToken(); if (scanner.hasMoreTokens()) error("SYNTAX ERROR"); Statement* inputstat = new Inputstmt(st); program.setParsedStatement(line_num, inputstat); program.addSourceLine(line_num, line); return; } if (token2 == "GOTO") { string token_tmp = scanner.nextToken(); TokenType type = scanner.getTokenType(token_tmp); if (type != NUMBER) error("SYNTAX ERROR"); if (scanner.hasMoreTokens()) error("SYNTAX ERROR"); int linenum = atoi(token_tmp.c_str()); Statement* gotostat = new Gotostmt(linenum); program.setParsedStatement(line_num, gotostat); program.addSourceLine(line_num, line); return; } if (token2 == "IF") { TokenScanner Lscanner; TokenScanner Rscanner; string left, right, tmp, cmp; while (scanner.hasMoreTokens()) { tmp = scanner.nextToken(); if (tmp == "=" || tmp == ">" || tmp == "<") { cmp = tmp; break; } else left = left + tmp; } if (cmp != "="&&cmp != "<"&&cmp != ">") error("SYNTAX ERROR"); while (scanner.hasMoreTokens()) { tmp = scanner.nextToken(); if (tmp == "THEN") break; else right = right + tmp; } if (tmp != "THEN") error("SYNTAX ERROR"); string token_tmp = scanner.nextToken(); TokenType type = scanner.getTokenType(token_tmp); if (type != NUMBER) error("SYNTAX ERROR"); if (scanner.hasMoreTokens()) error("SYNTAX ERROR"); int linenum = atoi(token_tmp.c_str()); Lscanner.setInput(left); Rscanner.setInput(right); Expression *lexp = parseExp(Lscanner); Expression *rexp = parseExp(Rscanner); Statement* ifstat = new Ifstmt(lexp, rexp, cmp, linenum); program.setParsedStatement(line_num, ifstat); program.addSourceLine(line_num, line); return; } if (token2 == "END") { Statement* endstat=new Endstmt(); program.setParsedStatement(line_num, endstat); program.addSourceLine(line_num, line); return; } error("SYNTAX ERROR"); } else error("SYNTAX ERROR"); }
/* Function: scanFormulaString() * ----------------------------- * Recursively scanns formula string and sorts each token through stacks due to shunting-yard * algorithm. If "()" appear in this recursion it controls brackets condition. Detects two * pow, sqrt - additional library function in user formula. Breaks process due to global * failFlag. Returns double of calculated result. In case of process faults zero result * is returned, and fail message is shown. * * @param scanner Scanner for main formula string * @param bracketsOpenedBefore Brackets were opened before this recursion invocation */ double scanFormulaString(TokenScanner& scanner, bool& bracketsOpenedBefore) { if (FAIL_FLAG) { return 0; //Global flag apearance } Stack<double> numbersStack; //Stacks for Shunting-Yard process Stack<string> operatorsStack; //in current recursion invocation string token = ""; bool bracketsOpenedHere = false;//Rises if "(" appear in this recursion /* Main string scanning. It stops due to conditions: * - end of formula string * - closed brackets condition * - FAIL_FLAG appearance */ while (scanner.hasMoreTokens()) { token = scanner.nextToken(); if (token == "pow") { /* Lunches library pow function process */ double powResult = powFunction(scanner); numbersStack.push(powResult); }else if (token == "sqrt") { /* Lunches library sqrt function process */ double sqrtResult = sqrtFunction(scanner); numbersStack.push(sqrtResult); }else{//Numbers, brackets or garbage symbol occur cases if (token == "(") { bracketsOpenedHere = true; /* Calls new formula recursion for this scanner */ numbersStack.push(scanFormulaString(scanner, bracketsOpenedHere)); }else if (token == ")") { if (bracketsOpenedBefore) { //Brackets are closed correctly bracketsOpenedBefore = false;//it is end of this recursion break; }else {//Token is ")" and no bracketsOpenedBefore flag FAIL_FLAG = true; //Brackets weren't opened cout << " - NOT OPENED BRACKETS! " << endl; break; //Break to show error to user } }else { if (FAIL_FLAG) { break;//Break if some faults appear in this recursion } /* Call Shunting-Yard sorting for this token */ sortTokenByStacks(token, numbersStack, operatorsStack); } } }//End of while(scanner.hasMoreTokens()) /* Shunting-yard final calculation */ if (bracketsOpenedBefore) {//If brackets haven't been closed in this recursion cout << " - NOT CLOSED BRACKETS! " << endl; FAIL_FLAG = true; return 0; } else { if (FAIL_FLAG) {//Main scanning cycle was breaked by some faults return 0; } else { /* Final stacks processing */ return getFinalStacksResult(numbersStack, operatorsStack); } } }
InputStmt::InputStmt(TokenScanner &scanner) { identifier = scanner.nextToken(); if (scanner.hasMoreTokens()) { error("Extraneous token " + scanner.nextToken()); } }
EndStmt::EndStmt(TokenScanner &scanner) { if (scanner.hasMoreTokens()) { error("Extraneous token " + scanner.nextToken()); } }
GotoStmt::GotoStmt(TokenScanner &scanner) { lineNumber = stringToInteger(scanner.nextToken()); if (scanner.hasMoreTokens()) { error("Extraneous token " + scanner.nextToken()); } }
/* main() manages the user interface; * instantiates priority queue object, then operates loop to read input * from user and call the appropriate priority queue method */ int main() { PriorityQueue pq; TokenScanner scanner; while (true) { string line = getLine("> "); scanner.setInput(line); scanner.ignoreWhitespace(); string cmd=scanner.nextToken(); if (cmd == "help") { helpCommand(); } else if (cmd == "enqueue") { if(scanner.hasMoreTokens()){ string value=scanner.nextToken(); if(scanner.hasMoreTokens()){ scanner.scanNumbers(); string priorityStr=scanner.nextToken(); double priority=stringToDouble(priorityStr); pq.enqueue(value,priority); } else pq.enqueue(value); } } else if (cmd == "dequeue") { if(pq.isEmpty()) cout<<"The queue is empty"<<endl; else cout<<pq.dequeue()<<endl; } else if (cmd == "peek") { if(pq.isEmpty()) cout<<"The queue is empty"<<endl; else cout<<pq.peek()<<endl; } else if (cmd == "peekPriority"||cmd=="peekpriority") { if(pq.isEmpty()) cout<<"The queue is empty"<<endl; else cout<<pq.peekPriority()<<endl; } else if (cmd == "clear") { pq.clear(); } else if (cmd == "size") { cout<<pq.size()<<endl; } else if (cmd == "isEmpty"||cmd=="isempty") { if(pq.isEmpty()) cout<<"true"; else cout<<"false"; cout<<endl; } else if(cmd=="list") list(pq); else { cout << "Undefined command: " << cmd << endl; } } return 0; }
/* * Function: specificHelp * Usage: specificHelp(scanner); * --------------------- * Displays a specialized help message depending on user input. */ void specificHelp(TokenScanner & scanner) { string specificHelp = toUpperCase(scanner.nextToken()); if (specificHelp == "REM") { cout << "Help for REM" << endl; cout << "------------" << endl; cout << "Use REM to comment your code. You can type in anything" << endl; cout << "after REM and it will be ignored. Example:" << endl; cout << "10 REM This is an example of commenting" << endl; } else if (specificHelp == "LET") { cout << "Help for LET" << endl; cout << "------------" << endl; cout << "Use LET to set a variable to an expression. You can declare" << endl; cout << "a new variable on the left side of the equals sign, but remember" << endl; cout << "to only use constants or variables you have already initialized" << endl; cout << "on the right side of the equals sign. If you use doubles, make" << endl; cout << "sure to include a number before the decimal point. Example:" << endl; cout << "10 LET x = y + 2.1" << endl << endl; cout << "You can also create a LET statement without the LET keyword. Example:" << endl; cout << "10 x = y + 2.1" << endl; } else if (specificHelp == "PRINT") { cout << "Help for PRINT" << endl; cout << "------------" << endl; cout << "Use PRINT to print a value. You can print strings and expressions" << endl; cout << "separated by commas. Example:" << endl; cout << "10 PRINT \"Countdown in T minus \", time" << endl; } else if (specificHelp == "INPUT") { cout << "Help for INPUT" << endl; cout << "------------" << endl; cout << "Use INPUT to prompt the user for values. The program will prompt" << endl; cout << "the user with ' ? ' and the variable following INPUT will be set" << endl; cout << "to the value that the user enters. Example:" << endl; cout << "10 INPUT x" << endl; } else if (specificHelp == "GOTO") { cout << "Help for GOTO" << endl; cout << "------------" << endl; cout << "Use GOTO to jump to a line in the program. This is commonly used" << endl; cout << "for loops. Example:" << endl; cout << "10 GOTO 5" << endl; } else if (specificHelp == "IF") { cout << "Help for IF" << endl; cout << "------------" << endl; cout << "Use IF to create a conditional statement. If the condition is" << endl; cout << "satisfied, the program will jump to the line specified after THEN." << endl; cout << "A condition consists of an expression followed by an operator followed" << endl; cout << "by an expression. Valid operators are <, =, and >. Example:" << endl; cout << "10 IF x + 1 = y THEN 30" << endl; } else if (specificHelp == "END") { cout << "Help for END" << endl; cout << "------------" << endl; cout << "Use END to mark the end of the program. Example:" << endl; cout << "10 END" << endl; } else if (specificHelp == "RUN") { cout << "Help for RUN" << endl; cout << "------------" << endl; cout << "Type RUN to run a program." << endl; } else if (specificHelp == "LIST") { cout << "Help for LIST" << endl; cout << "------------" << endl; cout << "Type LIST to list all the lines in a program." << endl; cout << "Type LIST 3-5 to list lines 3 to 5 inclusive." << endl; } else if (specificHelp == "CLEAR") { cout << "Help for CLEAR" << endl; cout << "------------" << endl; cout << "Type CLEAR to delete all the lines in a program." << endl; } else if (specificHelp == "HELP") { cout << "Help for HELP" << endl; cout << "------------" << endl; cout << "What are you doing here? I thought you already knew" << endl; cout << "how to ask for help!" << endl; } else if (specificHelp == "QUIT") { cout << "Help for QUIT" << endl; cout << "------------" << endl; cout << "Type QUIT to exit this BASIC interpreter." << endl; } else if (specificHelp == "EXTENSIONS") { cout << "Help for EXTENSIONS" << endl; cout << "------------" << endl; cout << "Basic BASIC has actually become quite awesome. Here are" << endl; cout << "a list of extensions for this particular interpreter:" << endl << endl; cout << "Optional LET:" << endl; cout << "-------------" << endl; cout << "You do not need to type the LET keyword to create a LetStmt." << endl; cout << "Typing \"10 x = 3\" will assign x to 3." << endl << endl; cout << "Floating-point Numbers:" << endl; cout << "-------------" << endl; cout << "Expressions can use doubles instead of integers." << endl; cout << "Typing \"10 x = 3.14\" will assign x to 3.14." << endl << endl; cout << "Flexible PRINT:" << endl; cout << "-------------" << endl; cout << "Print can print string tokens as well." << endl; cout << "Typing \"10 PRINT \"Countdown in T minus \", time\" is valid." << endl << endl; cout << "Selective LIST:" << endl; cout << "-------------" << endl; cout << "You can choose to list selective lines." << endl; cout << "Typing LIST 30-50 will display lines 30 through 50 inclusive." << endl << endl; } }
/* Function: formulaStringScanning() * -----------------------------------------------------------------------------------------// * Recursively scanns formula string and sorts each token through stacks due to shunting-yard * algorithm. If "()" appear in this recursion it controls brackets condition. Detects two * pow, sqrt - additional library function in user formula. Breaks process due to global * failFlag. Returns double of calculated result. In case of process faults zero result * is returned, and fail message is shown. * * @param scanner Scanner for main formula string * @param bracketsOpenedBefore Brackets were opened before this recursion invocation * @param xValue Value for x variable in user equation */ double formulaStringScanning(TokenScanner& scanner, bool &bracketsOpenedBefore, double xValue) { if(failFlag) { return 0; //Global flag apearance } else { MyStack<double> stackNumbers;//Stacks for current recursion invocation MyStack<string> stackOperators; string token = ""; bool bracketsOpenedHere = false;//Rises if "(" appear in this recursion while(scanner.hasMoreTokens()) { token = scanner.nextToken(); if(token == "x") { /* Sabstitute x-token by user xValue param */ stackNumbers.push(xValue); } else if(token == "pow") { /* Lunches library pow function process */ stackNumbers.push(powFunction(scanner)); } else if(token == "sqrt") { /* Lunches library sqrt function process */ stackNumbers.push(sqrtFunction(scanner, xValue)); } else { //Brackets case if(token == "(") { bracketsOpenedHere = true; /* Calls new formula recursion for this scanner */ stackNumbers.push(formulaStringScanning(scanner, bracketsOpenedHere, xValue)); } else if(token == ")") { if(bracketsOpenedBefore) { //Brackets are closed correctly bracketsOpenedBefore = false;//it is end of this recursion break; } else { //Token is ")" and no bracketsOpenedBefore flag failFlag = true; //Brackets were opened cout << " - NOT OPENED BRACKETS! " << endl; break; //Break to show error to user } } else { if(failFlag)break; /* If no fails, and token is valid - lunches * Shunting-Yard sorting */ sortTokenByStacks(token, stackNumbers, stackOperators); } }//End of Brackets case else statement }//End of while(scanner.hasMoreTokens()) /* Shunting-yard final calculation */ if(bracketsOpenedBefore) { //If brackets haven't been closed in this recursion cout << " - NOT CLOSED BRACKETS! " << endl; failFlag = true; return 0; } else { if(failFlag) { //There were some other fails return 0; } else { /* Calculate main result, due to stacks, for current calculation stage. */ return getFinalStacksResult(stackNumbers, stackOperators); } } }//End of else statement (no failFlag at recursion start) }
/* * Function: processLine * Usage: processLine(line, program, state); * ----------------------------------------- * Processes a single line entered by the user. In this version, * the implementation does exactly what the interpreter program * does in Chapter 19: read a line, parse it as an expression, * and then print the result. In your implementation, you will * need to replace this method with one that can respond correctly * when the user enters a program line (which begins with a number) * or one of the BASIC commands, such as LIST or RUN. */ void processLine(string line, Program & program, EvalState & state) { TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); string token=scanner.nextToken(); TokenType type=scanner.getTokenType(token); int lineNumb; int priorLineNumb; if(type==NUMBER){ if(scanner.hasMoreTokens()){ program.addSourceLine(stringToInteger(token),line); Statement *stmt=parseStatement(scanner); program.setParsedStatement(stringToInteger(token),stmt); //link statement to line number } else program.removeSourceLine(stringToInteger(token)); } if(type==WORD){ if(token=="LIST"){ lineNumb=program.getFirstLineNumber(); while(lineNumb!=-1){ cout<<program.getSourceLine(lineNumb)<<endl; lineNumb=program.getNextLineNumber(lineNumb); } } else if(token=="RUN"){ state.setCurrentLine(program.getFirstLineNumber()); lineNumb=state.getCurrentLine(); while(lineNumb!=-1){ if(program.hasLineNumber(lineNumb)==false) error("Invalid line reference at program line "+integerToString(priorLineNumb)); Statement *stmt=program.getParsedStatement(lineNumb); state.setCurrentLine(program.getNextLineNumber(lineNumb)); stmt->execute(state); priorLineNumb=lineNumb; lineNumb=state.getCurrentLine(); } } else if(token=="CLEAR"){ program.clear(); } else if(token=="HELP"){ cout<<"Minimal Basic Statements"<<endl; cout<<"REM This statement used for comments"<<endl; cout<<"LET This statement is BASIC's assigment statement"<<endl; cout<<"PRINT In minimal BASIC, the PRINT statement has the form: "<<endl; cout<<" PRINT exp"<<endl; cout<<" where exp is an expression."<<endl; cout<<"INPUT In the minimal version of the BASIC interpreter, the INPUT statement has the form:"<<endl; cout<<" INPUT var"<<endl; cout<<" where var is a variable read in from the user"<<endl; cout<<"GOTO This statement has the syntax"<<endl; cout<<" GOTO n"<<endl; cout<<" which forces the program to continue from line n instead of continuing with the next statement"<<endl; cout<<"IF This statement provides conditional control. The syntax for this statement is: "<<endl; cout<<" IF exp1 op exp2 THEN n"<<endl; cout<<" where exp1 and exp2 are expressions and op is one of the conditional operators =, <, or >."<<endl; cout<<"END This statment marks the end of the program."<<endl; cout<<"Commands to control the BASIC interpreter"<<endl; cout<<"RUN This command starts program execution beginning at the lowest-numbered line. "<<endl; cout<<"LIST This command lists the steps in the program in numerical sequence."<<endl; cout<<"CLEAR This command deletes the program so the user can start entering a new one."<<endl; cout<<"HELP This command provides a simple help message describing the interpreter."<<endl; cout<<"QUIT Typing QUIT exits from the BASIC interpreter by calling exit(0)."<<endl; } else if(token=="QUIT"){ exit(0); } else cout<<"Invalid command"<<endl; } }