Опубликован: 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("Введите формулу -> ")); } }