Rambler's Top100

Исходный файл CUPCalc.cup (все изменения выделены):

// JavaCup specification for a simple expression evaluator
import java_cup.runtime.*;
import java.io.*;
parser code {:
    public String parsingLine = null;
    int scanPos = 0;
    public void setParsingLine(String s) {
        parsingLine = s;
        scanPos = 0;
    }
    void initScanner() {
        scanPos = 0;
    }
    // Simple scanner
    Symbol next_token() {
        // Skip a space
        while (
            scanPos < parsingLine.length() &&
            Character.isWhitespace(parsingLine.charAt(scanPos))
        ) {
            scanPos++;
        }
        if (scanPos == parsingLine.length()) {
            scanPos++; return new Symbol(sym.EOL); // End of line
        } else if (scanPos > parsingLine.length()) {
            return new Symbol(sym.EOF);
        }
        char curChar = parsingLine.charAt(scanPos);
        if (Character.isDigit(curChar)) {
            // Extract a number
            String number = "" + curChar; scanPos++;
            while (
                scanPos < parsingLine.length() &&
                Character.isDigit(parsingLine.charAt(scanPos))
            ) {
                number += parsingLine.charAt(scanPos);
                scanPos++;
            }
            if (
                scanPos < parsingLine.length() &&
                parsingLine.charAt(scanPos) == '.'
            ) {
                number += '.'; scanPos++;
                //Part after a decimal point
                while (
                    scanPos < parsingLine.length() &&
                    Character.isDigit(parsingLine.charAt(scanPos))
                ) {
                    number += parsingLine.charAt(scanPos);
                    scanPos++;
                }
            }
            Double val = null;
            try {
                val = new Double(number);
            } catch (NumberFormatException e) {
                System.err.println("" + e);
            }
            return new Symbol(sym.NUMBER, val);
        } else if (curChar == '+') {
            scanPos++; return new Symbol(sym.PLUS);
        } else if (curChar == '-') {
            scanPos++; return new Symbol(sym.MINUS);
        } else if (curChar == '*') {
            scanPos++; return new Symbol(sym.TIMES);
        } else if (curChar == '/') {
            scanPos++; return new Symbol(sym.DIVIDE);
        } else if (curChar == '(') {
            scanPos++; return new Symbol(sym.LPAREN);
        } else if (curChar == ')') {
            scanPos++; return new Symbol(sym.RPAREN);
        } else {
            System.err.println("Error token");
            scanPos++; return new Symbol(sym.ERROR);
        }
    }
    public static void main(String args[]) {
        String line;
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(System.in)
        );
        parser parser_obj = new parser();
        while (true) {
            System.out.println(
                "Input an expression to evaluate (empty for end):"
            );
            try {
                line = reader.readLine();
            } catch (IOException e) {
                System.err.println("Read error: " + e);
                break;
            }
            if (line.equals("")) break;
            parser_obj.setParsingLine(line);
            try {
                // Parse a line
                Symbol s = parser_obj.parse();
                if (s != null && s.value != null) {
                    System.out.println("= " + (Double)s.value);
                } else {
                    System.out.println("Error expression");
                }
            } catch (Exception e) {
                System.err.println("" + e);
            }
        }
    }
:};
/* Preliminaries to set up and use the scanner.  */
init with {: initScanner(); :};
scan with {: return next_token(); :};
/* Terminals (tokens returned by the scanner). */
terminal        PLUS, MINUS, TIMES, DIVIDE;
terminal        UMINUS, LPAREN, RPAREN;
terminal        EOL, ERROR;
terminal Double NUMBER;
/* Non terminals */
//
//-----------------------------------------------------
non terminal String expression;
non terminal String expr;
//-----------------------------------------------------
//
/* Precedences */
precedence left PLUS, MINUS;
precedence left TIMES, DIVIDE;
precedence left UMINUS, LPAREN;
start with expression;
/* The grammar */
expression ::= expr:e EOL
          {: RESULT = e; :}
          ;
expr      ::= 
//
//---------------------------------------------------------------
	  expr:e1 PLUS expr:e2
          {: RESULT = new String(e1 + ", " + e2 + ", " + "+"); :}
          |
          expr:e1 MINUS expr:e2
          {: RESULT = new String(e1 + ", " + e2 + ", " + "-"); :}
          |
          expr:e1 TIMES expr:e2
          {: RESULT = new String(e1 + ", " + e2 + ", " + "*"); :}
          |
          expr:e1 DIVIDE expr:e2
          {: RESULT = new String(e1 + ", " + e2 + ", " + "/"); :}
          |
          NUMBER:n
          {: RESULT = new String("" + n); :}
          |
          MINUS expr:e
          {: RESULT = new String(e + ", " + "--"); :}
          %prec UMINUS
          |
//-------------------------------------------------------------------
//
          LPAREN expr:e RPAREN
          {: RESULT = e; :}
          ;
Хостинг от uCoz