Rambler's Top100

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

CUPCalc.cup

// JavaCup specification for a simple expression evaluator
import java_cup.runtime.*;
import java.io.*;
//
//-----------------------------------------------------------
import Der;
//------------------------------------------------------------
//
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++;
                }
            }
            Integer val = null;
            try {
                val = new Integer(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 == 'x') {
            scanPos++; return new Symbol(sym.X);
        } 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("= " + (Integer)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        MINUS, PLUS, TIMES;
terminal        LPAREN, RPAREN;
terminal        EOL, ERROR;
terminal String   X;
terminal Integer NUMBER;
//--------------------------------------------------
//
/* Non terminals */
non terminal String expression;
non terminal String expr;
/* Precedences */
//
//-------------------------------------------------
precedence left PLUS, MINUS;
precedence left TIMES;
precedence left LPAREN;
//-------------------------------------------------
//
start with expression;
/* The grammar */
expression ::= expr:e EOL
          {: RESULT = e; :}
          ;
//
//----------------------------------------------------------------------
expr      ::= expr:e1 PLUS expr:e2
          {:String f1 = Der.function(e1);
            String d1 = Der.derivation(e1);
            String f2 = Der.function(e2);
            String d2 = Der.derivation(e2);
            if (f1 != "nf" && f2 != "nf") RESULT = new String("("+f1 + " + " + f2 +")!(" + d1 + " + " + d2+")"); 
                else if (f1 == "nf" && f2 != "nf") RESULT = new String("("+e1 + " + " + f2 + ")!" + d2);
                else if (f1 != "nf" && f2 == "nf") RESULT = new String("("+f1 + " + " + e2 + ")!" + d1);
                else RESULT = new String(e1 + "+" + e2 + "!0");
          :}           
          |
          expr:e1 MINUS expr:e2
          {:String f1 = Der.function(e1);
            String d1 = Der.derivation(e1);
            String f2 = Der.function(e2);
            String d2 = Der.derivation(e2);
            if (f1 != "nf" && f2 != "nf") RESULT = new String("("+f1 + " - " + f2 +")!(" + d1 + " - " + d2 +")"); 
                else if (f1 == "nf" && f2 != "nf") RESULT = new String("(" + e1 + " - " + f2 + ")!" + d2);
                else if (f1 != "nf" && f2 == "nf") RESULT = new String("(" + f1 + " - " + e2 + ")!" + d1);
                else RESULT = new String(e1 + "-" + e2 + "!0");
          :}           
          |
          expr:e1 TIMES expr:e2
          {:
            String f1 = Der.function(e1);
            String d1 = Der.derivation(e1);
            String f2 = Der.function(e2);
            String d2 = Der.derivation(e2);
            
            if (f1 != "nf" && f2 != "nf") RESULT = new String(f1 + " * " + f2 +"!(" + d1 + " * " + f2 + " + " + f1 + " * " + d2 + ")"); 
                else if (f1 == "nf" && f2 != "nf") RESULT = new String(e1 + " * " + f2 + "!" + e1 + " * " + d2);
                else if (f1 != "nf" && f2 == "nf") RESULT = new String(f1 + " * " + e2 + "!" + d1 + " * " + e2);
                else RESULT = new String(e1 + " * " + e2 + "! ");
          :}
          |
          NUMBER:n
          {: RESULT = n.toString(); :}
          |
          X:n
          {: RESULT = "x!1"; :}
          |
          LPAREN expr:e RPAREN
          {: RESULT = e; :}
          ;
//------------------------------------------------------------------------
//

CUPCalc.java

/**
 * Calculator of ariphmetic expressions
 * Uses CUP (Java version of YACC) technology
 */
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
//
//-----------------------------------------------------------
import Der;
//-----------------------------------------------------------
//
import java_cup.runtime.*;  // CUP runtime environment
import parser;  // Parser generated by CUP from the file "CUPCalc.cup"
public class CUPCalc extends Applet {
    Button evaluateButton;
    TextField expression;
    TextField result;
    // Layout constants
    static final int margin         = 5;
    static final int headlineHeight = 30;
    static final int vertSkip       = 5;
    static final int horSkip        = 5;
    static final int labelWidth     = 80;
    static final int textWidth      = 300;
    static final int buttonWidth    = 80;
    static final int buttonHeight   = 30;
    public static void main(String[] args) {
        Frame f = new Frame("CUP Calculator");
        WindowAdapter wa = new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        };
        f.addWindowListener(wa);
        f.setFont(new Font("Helvetica", Font.PLAIN, 14));
        // Add menu bar
        final MenuBar mb = new MenuBar();
        f.setMenuBar(mb);
        final Menu fileMenu = new Menu("File");
        final MenuItem quitItem = new MenuItem("Quit");
        fileMenu.add(quitItem);
        mb.add(fileMenu);
        ActionListener al = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // System.out.println("Action " + e);
                if (e.getActionCommand().equals("Quit")) {
                    System.exit(0);
                }
            }
        };
        fileMenu.addActionListener(al);
        CUPCalc cc = new CUPCalc();
        f.add("Center", cc);
        // f.pack();
        f.setSize(
            2*margin + labelWidth + horSkip + textWidth + 10,
            2*margin + headlineHeight + 4*buttonHeight + 3*vertSkip + 50
        );
        cc.init();
        cc.start();
        f.setVisible(true);
    }
    public void init() {
        setLayout(null);
        setFont(new Font("Helvetica", Font.PLAIN, 14));
        setBackground(Color.lightGray);
//
//-------------------------------------------------------------
        Label headline = new Label("Computing the derivation of algebraic function");
//-------------------------------------------------------------
//
        headline.setFont(new Font("TimesRoman", Font.BOLD, 18));
        add(headline);
        int x = margin;
        int y = margin;
        headline.setBounds(x, y, 380, 30);
        y += headlineHeight + vertSkip;
        Label l = new Label("Expression:");
        add(l);
        l.setBounds(x, y, labelWidth, buttonHeight);
        x += labelWidth + horSkip;
        expression = new TextField();
        add(expression);
        expression.setBounds(x, y, textWidth, buttonHeight);
        y += buttonHeight + vertSkip;
        evaluateButton = new Button("Derivate");
        add(evaluateButton);
        x += (textWidth - buttonWidth);
        evaluateButton.setBounds(x, y, buttonWidth, buttonHeight);
        y += buttonHeight + vertSkip;
        x = margin;
        l = new Label("Result:");
        add(l);
        l.setBounds(x, y, labelWidth, buttonHeight);
        x += labelWidth + horSkip;
        result = new TextField();
        result.setEditable(false);
        add(result);
        result.setBounds(x, y, textWidth, buttonHeight);
        result.setForeground(Color.blue);
        // Add action listener for "Expression" text field
        // (for processing of the "Enter" button) and "Evaluate" button
        ActionListener al = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // System.out.println("Text action " + e);
                onEvaluate();
            }
        };
        expression.addActionListener(al);
        evaluateButton.addActionListener(al);
        // That's all.
    }
    // Evaluate an expression
    void onEvaluate() {
        parser parser_obj = new parser();
        parser_obj.setParsingLine(expression.getText());
        try {
            // Parse a line
            Symbol s = parser_obj.parse();
//
//-----------------------------------------------------  
            if (s != null && s.value != null) {
                result.setText(Der.derivation("" + s.value));
            } else {
                result.setText("Syntax error");
            }
//-----------------------------------------------------
//
        } catch (Exception e) {
            //... System.err.println("" + e);
            result.setText("Syntax error");
        }
    }
}

Der.java

public class Der {
     static String function(String s) {
        int index = s.indexOf("!");
        if (index != -1) return s.substring(0, index);
           else return("nf");
     }
     static String derivation(String s) {
        int index = s.indexOf("!");
        if (index != -1) return s.substring(index + 1, s.length());
           else return("nf");
     }
}
Хостинг от uCoz