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