Читаем Программирование на языке Ruby полностью

     processSuspendedSymbol(c)

     pop

when SYM_OPER

     processSuspendedSymbol(c)

     push(c)

when SYM_OTHER

     nextOther(c)

     end

end

def processSuspendedSymbol(c)

while precedes(top, c)

     nextOper(pop)

     end

end


Работа начинается с вызова метода compile, в котором все символы строки str последовательно передаются методу processSymbol.


def priority(c)

     (c == ’+’ or c == ’-’) ? 1 : 2 end

def precedes(a, b)

     return false if symType(a) == SYM_LEFT

return true

if symType(b) == SYM_RIGHT

     priority(a) >= priority(b) end

     protected

     SYM_LEFT = 0; SYM_RIGHT = 1; SYM_OPER = 2; SYM_OTHER = 3

def symOther(c)


# Сравнение символа с образцом (регулярным выражением).

raise "Недопустимый символ #{c}" if c !~ /[a-z]/

     SYM_OTHER

end

def nextOper(c)

     print "#{c} "

end


def nextOther(c)

     nextOper(c)

     end

end


Квалификатор доступа protected и метод nextOther нужны для создания на базе класса Compf нового класса Calc, реализующего калькулятор формул[13].

Класс Calc (калькулятор числовых формул) выведен из класса Compf, переопределяет некоторые методы последнего, и имеет дополнительный стек для размещения в нём чисел. Калькулятор работает только с цифрами (числами от 0 до 9).

Несколько комментариев к методу nextOper(c) класса Calc. Множественное присваивание в первой строке метода корректно, т.к. в языке Ruby при выполнении множественного (параллельного) присваивания сначала последовательно вычисляются все выражения в правой части оператора присваивания.


require ’Compf’

class Calc < Compf def initialize

# Вызов метода initialize базового класса Compf. super

# Создание стека результатов операций.


@s = Stack.new

end

def compile(str) super

return @s.top end

protected

def symOther(c)

raise "Недопустимый символ #{c}" if c !~ /[0-9]/ SYM_OTHER end

def nextOper(c)

second, first = @s.pop, @s.pop @s.push(first.method(c).call(second)) end

def nextOther(c)

@s.push(c.to_i)

end

end


Конструкция first.method(c).call(second) во второй строке метода может быть объяснена таким примером: выражение 3.metod(’-’).call(2), эквивалентно выражению 3. – (2) или просто 3-2.


Задача 1. Добавьте операции sin, cos и унарный минус.

Задача 2. Добавьте правоассоциативную операцию ~ возведения в степень.

Задача 3. Добавьте квадратные и фигурные скобки.

Задача 4. Измените программу так, чтобы допускались в качестве имен переменных произвольные идентификаторы языка Ruby.

Задача 5. Добавьте левоассоциативную операцию % с приоритетом, равным приоритету операции /.

Задача 6. Добавьте возможность записи формулы с пробелами и комментариями двух типов (/* */ и //).

Задача 7. Измените программу так, чтобы ввод, содержащий в качестве аргументов только восьмеричные числа (начинающиеся с нуля, например 056), компилировался в программу, содержащую десятичные числа.

Задача 8. Измените программу так, чтобы ввод, содержащий в качестве аргументов только шестнадцатеричные числа (начинающиеся с 0x, например 0x56), компилировался в программу, содержащую восьмеричные числа.

Задача 9. Измените программу так, чтобы ввод, содержащий в качестве аргументов только римские числа, не превосходящие 5000, компилировался в программу, содержащую десятичные числа.

Задача 10. Измените программу так, чтобы для коммутативной операции аргументы выдавались в алфавитном порядке.

Задача 11. Добавьте фигурные скобки, означающие возведение в квадрат. Используйте операцию DUP стекового калькулятора.

Задача 12. Считая, что a = 0, оптимизируйте формулу (уберите лишние сложения).

Задача 13. Считая, что b = 1, оптимизируйте формулу (уберите лишние умножения).

Задача 14. Добавьте возможность ввода формулы на нескольких строках.

Три шага к свободному ПО

Не все знают, что стоимость проприетарного (коммерческого) программного обеспечения, способного превратить «компьютерное железо» в современный компьютер, значительно больше стоимости самого «железа». Не знают зачастую потому, что используют контрафактное (то есть приобретённое без лицензии) ПО, что является нарушением действующего законодательства.

Перейти на страницу:

Похожие книги

Фундаментальные алгоритмы и структуры данных в Delphi
Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет СЃРѕР±РѕР№ уникальное учебное и справочное РїРѕСЃРѕР±ие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий DelphiВ».Р' книге РїРѕРґСЂРѕР±но рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием. Р

Джулиан М. Бакнелл

Программирование, программы, базы данных