"Джек Креншоу. Давайте создадим компилятор! " - читать интересную книгу авторастек пишется как
-(SP) и извлечение (SP)+. Итак, изменим EmitLn в процедуре Expression на EmitLn('MOVE D0,-(SP)'); и две строки в Add и Subtract: EmitLn('ADD (SP)+,D0') и EmitLn('SUB (SP)+,D0') соответственно. Теперь испытаем компилятор снова и удостоверимся что он работает. И снова, полученный код менее эффективен, чем был до этого, но это необходимый шаг, как вы увидите. УМНОЖЕНИЕ И ДЕЛЕНИЕ Теперь давайте возьмемся за действительно серьезные дела. Как вы знаете, кроме операторов "addops" существуют и другие... выражения могут также иметь операторы умножения и деления. Вы также знаете, что существует неявный приоритет операторов или иерархия, связанная с выражениями, чтобы в выражениях типа 2 + 3 * 4, мы знали, что нужно сначала умножить, а затем сложить. (Видите, зачем нам нужен стек? ) довольно сложные методы для того чтобы правила приоритета операторов соблюдались. Но, оказывается, все же, что ни один из них нам не нужен... эти правила могут быть очень хорошо применены в нашей технике нисходящего синтаксического анализа. До сих пор единственной формой, которую мы применяли для терма была форма одиночной десятичной цифры. В более общей форме мы можем определить терм как произведение показателей (product of factors), то есть одиночной цифрой. Обратите внимание: терм имеет ту же форму, что и выражение. Фактически, мы можем добавить это в наш компилятор осторожно скопировав и переименовав. Но во избежание неразберихи ниже приведен полный листинг всех подпрограмм анализатора. (Заметьте способ, которым мы изменяем порядок операндов в Divide.) {-} { Parse and Translate a Math Factor } procedure Factor; begin EmitLn('MOVE #' + GetNum + ',D0') end; {-} { Recognize and Translate a Multiply } |
|
|