Exemplo n.º 1
0
/**
 * 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);
    }
  }
}
Exemplo n.º 2
0
Arquivo: expeval.c Projeto: siva82kb/C
/**
 * 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 ("");
};