/** * Parse a line, fill l2rTable accordingly * Recursive function * * @param line * @param linePos * @param stringLevelStack * @param level */ void Grammar::parseLineRecursively(const char * line, int linePos, stack <stringAndInt> stringLevelStack, int level) { char nextChar = line[linePos]; // cout << "nextChar: " << nextChar << endl; while (nextChar == ' ' && linePos < strlen(line)) { linePos++; nextChar = line[linePos]; } if ((linePos >= strlen(line) - 1) || !validCharacter(nextChar)) // check for e.g. tab-characters in input file return; else { if (nextChar == ')') { // ========> non-terminal rule (RHS end) found stringAndInt RHS1, RHS2, LHS; RHS2 = stringLevelStack.top(); stringLevelStack.pop(); if (stringLevelStack.top().second == RHS2.second) { // same level RHS1 = stringLevelStack.top(); stringLevelStack.pop(); RHS1.first += " " + nonTerminalSymbol; } else { RHS1.first = ""; } LHS = stringLevelStack.top(); //stringLevelStack.pop(); insertL2rTable(nonTerminalSymbol + LHS.first, nonTerminalSymbol + RHS1.first + RHS2.first); //cout << "insert " << LHS.first << " ==> " << RHS1.first + RHS2.first << endl; return parseLineRecursively(line, linePos + 1, stringLevelStack, level - 1); } if (nextChar != ')' && nextChar != '(') { // ========> non-terminal LHS found string nonTerm = ""; while (line[linePos] != ' ') { nonTerm += line[linePos]; linePos++; } //cout << "nonterm: " << nonTerm << endl; stringLevelStack.push(stringAndInt(nonTerm, level)); //cout << "enter " << nonTerm << " at stack at level " << level << endl; linePos++; // go beyond space nextChar = line[linePos]; } if (nextChar == '(') { // ========> begin new rule found (new LHS) return parseLineRecursively(line, linePos + 1, stringLevelStack, level + 1); } else { // ========> terminal symbol + ')' found string term = ""; while (line[linePos] != ')') { term += line[linePos]; linePos++; } //cout << "term: " << term << endl; string nonTerm = stringLevelStack.top().first; insertL2rTable(nonTerminalSymbol + nonTerm, term); //cout << "insert " << nonTerm << " ==> " << term << endl; return parseLineRecursively(line, linePos + 1, stringLevelStack, level - 1); } } }
/** * Check if the given expression is a valid. * @param expr [Expression that is to be tested] * @return Returns the error message about the expression. When the * returned message is empty, it indicates a proper expression. */ char* checkInfixExpression(char* expr) { char *err = malloc(sizeof(char) * 256); int r; int b_count = 0; int prev_b_loc[2]; int N = strlen(expr); for(r = 0; expr[r]; r++) { // check if this is a valid Infix expression character. if (validCharacter(expr[r]) == false) { sprintf(err, "Invalid character \'%c\' in expression.", expr[r]); return (err); } // the first character can be a number, '.' or '-', and nothing else. if (r == 0 && !isNumber(expr[r]) && expr[r] != '.' && expr[r] != '-' && expr[r] != '(') { sprintf(err, "The first character of the expression must be number or a '-'."); return (err); } // check if the current character is a operator. if (isOperator(expr[r])) { // Then the next character must be a number, (, '.' or a -sign. if (!isNumber(expr[r+1]) && expr[r+1] != '(' && expr[r+1] != '.' && expr[r+1] != '-') { // this is not valid. sprintf(err, "When two operators are together, then the second one can only be a '-' sign."); return (err); } } // check to make sure there aren't two '.' next to each other. if (expr[r] == '.' && expr[r+1] == '.') { sprintf(err, "There cannot be two consecutive '.'s in the epxression."); return (err); } // check if the character is a bracket. if (expr[r] == '(') { // check that the character before '(' is a operator or another '(' if (r > 0 && isNumber(expr[r-1]) || expr[r-1] == '.' || expr[r-1] == ')') { sprintf(err, "The character preceeding a ( must be an operator or (."); return (err); } else if (r < N-1 && expr[r+1] == ')' || (isOperator(expr[r+1]) && expr[r+1] != '-')) { sprintf(err, "The character following a ( must be either a number or -."); return (err); } else if (r == N-1) { sprintf(err, "The expression cannot end with (."); return (err); } b_count++; } if (expr[r] == ')') { // check that the character before '(' is a operator or another '(' if (r > 0 && isOperator(expr[r-1]) || expr[r-1] == '(') { sprintf(err, "The character preceeding a ) cannot be a operator or (."); return (err); } else if (r < N-1 && isNumber(expr[r+1]) || expr[r-1] == '.' || expr[r+1] == '(') { sprintf(err, "The character following a ) cannot be a number or (."); return (err); } else if (r == 0) { sprintf(err, "The expression cannot start with )."); return (err); } b_count--; } } // make sure the barckets match. if (b_count != 0) { sprintf(err, "The brackets do not match."); return (err); } return (""); };