Опубликован: 27.09.2006 | Уровень: для всех | Доступ: платный | ВУЗ: Московский государственный индустриальный университет
Лекция 12:

Проект "Компилятор формул"

Теперь приведем все исходные тексты, относящиеся к стековому компилятору формул и интерпретатору.

Makefile для стекового компилятора и интерпретатора формул

# -*- mode: makefile -*-

.PHONY : compf calc clean

# Запустить тест стекового компилятора формул.
compf:			CompfTest.class
	java CompfTest

# Откомпилировать текст стекового компилятора формул.
CompfTest.class:	CompfTest.java Compf.java Xterm.java
	javac CompfTest.java

# Запустить тест калькулятора формул.
calc:			CalcTest.class
	java CalcTest

# Откомпилировать текст калькулятора формул.
CalcTest.class:		CalcTest.java Calc.java Compf.java Xterm.java
	javac CalcTest.java

# Удалить лишние файлы.
clean:
	rm -f *.class *.expand

Стековый компилятор формул

// Непрерывная реализация стека символов.
class Stack {
    private static final int DEFSIZE = 16;
    private char[] array;
    private int    head;

    public Stack() {
        array = new char[DEFSIZE];
        head = 0; 
    }
    public final void push(char c) {
        array[head++] = c;
    }
    public final char pop() {
        return array[--head];
    }
    public final char top() {
        return array[head-1];
    }
} 
// Стековый компилятор формул.
public class Compf extends Stack {
    // Типы символов (скобки, знаки операции, иное).
    protected final static int SYM_LEFT  = 0,
                               SYM_RIGHT = 1,
                               SYM_OPER  = 2,
                               SYM_OTHER = 3;
    private int symType(char c) {
        switch (c) {
          case '(':
            return SYM_LEFT;
          case ')':
            return SYM_RIGHT;
          case '+': case '-': case '*': case '/':
            return SYM_OPER;
          default:
            return symOther(c);
        }
    }
    private void processSymbol(char c) {
        switch (symType(c)) {
          case SYM_LEFT:
            push(c); break;
          case SYM_RIGHT:
            processSuspendedSymbols(c); pop(); break;
          case SYM_OPER:
            processSuspendedSymbols(c); push(c); break;
          case SYM_OTHER:
            nextOther(c); break;
        }
    }
    private void processSuspendedSymbols(char c) {
        while (precedes(top(), c))
            nextOper(pop());
    }
    private int priority(char c) {
        return c == '+' || c == '-' ? 1 : 2;
    }
    private boolean precedes(char a, char b) {
        if(symType(a) == SYM_LEFT) return false;
        if(symType(b) == SYM_RIGHT) return true;
        return priority(a) >= priority(b);
    }
    protected int symOther(char c) {
        if (c < 'a' || c > 'z') {
            Xterm.println("Недопустимый символ: " + c);
            System.exit(0);
        }
        return SYM_OTHER;
    }	
    protected void nextOper(char c) {	
        Xterm.print("" + c + " ");
    }
    protected void nextOther(char c) {	
        nextOper(c);
    }

    public void compile(char[] str) { 
        processSymbol('(');
        for(int i = 0; i < str.length; i++)
            processSymbol(str[i]);
        processSymbol(')');
        Xterm.print("\n");
    }
}

Тест для стекового компилятора формул

// Тест для компилятора формул.
public class CompfTest {
    public static void main(String[] args) throws Exception {
        Compf c = new Compf();
        while (true)	       
            c.compile(Xterm.inputChars("Введите формулу -> "));	    
    }
}
Анастасия Халудорова
Анастасия Халудорова
екатерина яковлева
екатерина яковлева
Ирина Тютрина
Ирина Тютрина
Россия, Усолье-Сибирское
Глеб Бочкарёв
Глеб Бочкарёв
Россия