From 6da094ebbfffec6ab34e06e6af29ca8d065ae205 Mon Sep 17 00:00:00 2001 From: Arity-T Date: Thu, 22 May 2025 15:19:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BF=D0=B8=D0=BB=D1=8F?= =?UTF-8?q?=D1=82=D0=BE=D1=80=20=D0=B8=20=D0=B2=D0=BC=20=D0=BC=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab4/.gitignore | 4 + lab4/cmilan/doc/Makefile | 10 + lab4/cmilan/doc/cmilan.pdf | Bin 0 -> 259195 bytes lab4/cmilan/doc/cmilan.tex | 956 +++++++++ lab4/cmilan/src/Makefile | 23 + .../src/cmilan_vs2011/cmilan_vs2011.sln | 20 + .../src/cmilan_vs2011/cmilan_vs2011.vcxproj | 92 + .../cmilan_vs2011.vcxproj.filters | 42 + .../cmilan_vs2011/cmilan_vs2011.vcxproj.user | 3 + lab4/cmilan/src/codegen.cpp | 129 ++ lab4/cmilan/src/codegen.h | 100 + lab4/cmilan/src/codegen.o | Bin 0 -> 5991 bytes lab4/cmilan/src/main.cpp | 32 + lab4/cmilan/src/main.o | Bin 0 -> 20476 bytes lab4/cmilan/src/parser.cpp | 270 +++ lab4/cmilan/src/parser.h | 119 ++ lab4/cmilan/src/parser.o | Bin 0 -> 18027 bytes lab4/cmilan/src/scanner.cpp | 233 +++ lab4/cmilan/src/scanner.h | 164 ++ lab4/cmilan/src/scanner.o | Bin 0 -> 6500 bytes lab4/cmilan/test/add.mil | 7 + lab4/cmilan/test/comment.mil | 14 + lab4/cmilan/test/factorial.mil | 10 + lab4/cmilan/test/fib.mil | 17 + lab4/cmilan/test/gcd.mil | 17 + lab4/cmilan/test/if.mil | 8 + lab4/cmilan/test/invalid.mil | 5 + lab4/cmilan/test/invert.mil | 14 + lab4/cmilan/test/loop.mil | 17 + lab4/cmilan/test/power.mil | 14 + lab4/cmilan/test/read2.mil | 8 + lab4/cmilan/test/sum.mil | 9 + lab4/vm/bin/milanvm.exe | Bin 0 -> 82432 bytes lab4/vm/doc/changelog.txt | 10 + lab4/vm/doc/vm.txt | 224 +++ lab4/vm/vm/Makefile | 15 + lab4/vm/vm/lex.yy.c | 1690 ++++++++++++++++ lab4/vm/vm/main.c | 46 + lab4/vm/vm/test/bop1.ms | 6 + lab4/vm/vm/test/bop2.ms | 8 + lab4/vm/vm/test/fib.ms | 37 + lab4/vm/vm/test/fib2.ms | 21 + lab4/vm/vm/vm.c | 371 ++++ lab4/vm/vm/vm.h | 88 + lab4/vm/vm/vmlex.l | 51 + lab4/vm/vm/vmparse.tab.c | 1736 +++++++++++++++++ lab4/vm/vm/vmparse.tab.h | 79 + lab4/vm/vm/vmparse.y | 70 + 48 files changed, 6789 insertions(+) create mode 100644 lab4/.gitignore create mode 100644 lab4/cmilan/doc/Makefile create mode 100644 lab4/cmilan/doc/cmilan.pdf create mode 100644 lab4/cmilan/doc/cmilan.tex create mode 100644 lab4/cmilan/src/Makefile create mode 100644 lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.sln create mode 100644 lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj create mode 100644 lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.filters create mode 100644 lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.user create mode 100644 lab4/cmilan/src/codegen.cpp create mode 100644 lab4/cmilan/src/codegen.h create mode 100644 lab4/cmilan/src/codegen.o create mode 100644 lab4/cmilan/src/main.cpp create mode 100644 lab4/cmilan/src/main.o create mode 100644 lab4/cmilan/src/parser.cpp create mode 100644 lab4/cmilan/src/parser.h create mode 100644 lab4/cmilan/src/parser.o create mode 100644 lab4/cmilan/src/scanner.cpp create mode 100644 lab4/cmilan/src/scanner.h create mode 100644 lab4/cmilan/src/scanner.o create mode 100644 lab4/cmilan/test/add.mil create mode 100644 lab4/cmilan/test/comment.mil create mode 100644 lab4/cmilan/test/factorial.mil create mode 100644 lab4/cmilan/test/fib.mil create mode 100644 lab4/cmilan/test/gcd.mil create mode 100644 lab4/cmilan/test/if.mil create mode 100644 lab4/cmilan/test/invalid.mil create mode 100644 lab4/cmilan/test/invert.mil create mode 100644 lab4/cmilan/test/loop.mil create mode 100644 lab4/cmilan/test/power.mil create mode 100644 lab4/cmilan/test/read2.mil create mode 100644 lab4/cmilan/test/sum.mil create mode 100644 lab4/vm/bin/milanvm.exe create mode 100644 lab4/vm/doc/changelog.txt create mode 100644 lab4/vm/doc/vm.txt create mode 100644 lab4/vm/vm/Makefile create mode 100644 lab4/vm/vm/lex.yy.c create mode 100644 lab4/vm/vm/main.c create mode 100644 lab4/vm/vm/test/bop1.ms create mode 100644 lab4/vm/vm/test/bop2.ms create mode 100644 lab4/vm/vm/test/fib.ms create mode 100644 lab4/vm/vm/test/fib2.ms create mode 100644 lab4/vm/vm/vm.c create mode 100644 lab4/vm/vm/vm.h create mode 100644 lab4/vm/vm/vmlex.l create mode 100644 lab4/vm/vm/vmparse.tab.c create mode 100644 lab4/vm/vm/vmparse.tab.h create mode 100644 lab4/vm/vm/vmparse.y diff --git a/lab4/.gitignore b/lab4/.gitignore new file mode 100644 index 0000000..f7ea855 --- /dev/null +++ b/lab4/.gitignore @@ -0,0 +1,4 @@ +*.zip +*.cmil +cmilan/src/cmilan.exe +!cmilan/doc/cmilan.pdf diff --git a/lab4/cmilan/doc/Makefile b/lab4/cmilan/doc/Makefile new file mode 100644 index 0000000..a4b4448 --- /dev/null +++ b/lab4/cmilan/doc/Makefile @@ -0,0 +1,10 @@ +cmilan.pdf: cmilan.tex + pdflatex cmilan.tex + pdflatex cmilan.tex + pdflatex cmilan.tex + +clean: + rm -f cmilan.aux + rm -f cmilan.toc + rm -f cmilan.log + diff --git a/lab4/cmilan/doc/cmilan.pdf b/lab4/cmilan/doc/cmilan.pdf new file mode 100644 index 0000000000000000000000000000000000000000..172d61bfdc4fa2c710d3b1d020f4854ec83de71b GIT binary patch literal 259195 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

ppz4+(sUwvFFKc$0XoT<7XW$Hxpk1Hf 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%0A4pYH$gXNS9&K`e)_*nDnKB>#R3R0v$O#M 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 literal 0 HcmV?d00001 diff --git a/lab4/cmilan/doc/cmilan.tex b/lab4/cmilan/doc/cmilan.tex new file mode 100644 index 0000000..2a23eea --- /dev/null +++ b/lab4/cmilan/doc/cmilan.tex @@ -0,0 +1,956 @@ +\documentclass[a4paper,12pt]{article} +\usepackage{ucs} +\usepackage{cmap} +\usepackage[utf8x]{inputenc} +\usepackage[T2A]{fontenc} +\usepackage[english,russian]{babel} +\usepackage[hmargin=2cm,vmargin=2cm]{geometry} +\usepackage{indentfirst} +\usepackage{listings} +\usepackage{syntax} +\usepackage[section]{placeins} + +\setlength{\grammarparsep}{10pt plus 1pt minus 1pt} +\setlength{\grammarindent}{9em} + +\lstset{ + frame=TB, + morekeywords={begin,end,if,then,else,fi,while,do,od,write,read} +} + +\title{Компилятор \textsc{CMilan}} +\author{Р­. Р¤. Аллахвердиев, Р”. Рђ. Тимофеев} + +\begin{document} +\maketitle +\tableofcontents + +\section{РћР±Р·РѕСЂ языка Милан} + +Язык Милан --- учебный язык программирования, описанный РІ +учебнике~\cite{karpov05}. + +Программа РЅР° Милане представляет СЃРѕР±РѕР№ последовательность операторов, +заключенных между ключевыми словами \texttt{begin} Рё \texttt{end}. Операторы +отделяются РґСЂСѓРі РѕС‚ РґСЂСѓРіР° точкой СЃ запятой. После последнего оператора РІ блоке +точка СЃ запятой РЅРµ ставится. Компилятор \textsc{CMilan} РЅРµ учитывает регистр +символов РІ именах переменных Рё ключевых словах. + +Р’ базовую версию языка Милан РІС…РѕРґСЏС‚ следующие конструкции: константы, +идентификаторы, арифметические операции над целыми числами, операторы чтения +чисел СЃРѕ стандартного РІРІРѕРґР° Рё печати чисел РЅР° стандартный вывод, оператор +присваивания, условный оператор, оператор цикла СЃ предусловием. + +Программа может содержать комментарии, которые РјРѕРіСѓС‚ быть многострочными. +Комментарий начинается символами `\texttt{/*}' Рё заканчивается символами +`\texttt{*/}'. Вложенные комментарии РЅРµ допускаются. + +Грамматика языка Милан РІ расширенной форме Бэкуса-Наура приведена РЅР° +СЂРёСЃСѓРЅРєРµ~\ref{milan-grammar}. + +\begin{figure} +\begin{grammar} + + ::= `begin' `end' + + ::= `;' + \alt $\epsilon$ + + ::= `:=' + \alt `if' `then' [`else' ] `fi' + \alt `while' `do' `od' + \alt `write' `(' `)' + + ::= \{ \} + + ::= \{ \} + + ::= | | `(' `)' + + ::= + + ::= `+' | `-' + + ::= `*' | `/' + + ::= `=' | `!=' | `<' | `<=' | `>' | `>=' + + ::= \{ | \} + + ::= `a' | `b' | `c' | \ldots | `z' | `A' | `B' | `C' | \ldots | `Z' + + ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' + +\end{grammar} +\label{milan-grammar} +\caption{Грамматика языка Милан} +\end{figure} + +\subsection{Константы} + +Р’ языке реализована поддержка знаковых целочисленных констант. Синтаксически +константы представляют СЃРѕР±РѕР№ последовательность цифр, перед которой может +находиться знак `-'. Примеры констант: \texttt{0}, \texttt{9}, \texttt{1234}, +\texttt{-19}, \texttt{-0}. + +\subsection{Рдентификаторы} + +Рдентификаторы представляют СЃРѕР±РѕР№ последовательность Р±СѓРєРІ латинского алфавита Рё +цифр. Первым символом идентификатора должна быть Р±СѓРєРІР°. Максимальная длина +идентификатора ограничена 63 символами. Регистр символов РЅРµ учитывается. +Рдентификаторы РЅРµ должны совпадать СЃ ключевыми словами \texttt{begin}, +\texttt{end}, \texttt{if}, \texttt{then}, \texttt{else}, \texttt{fi}, +\texttt{do}, \texttt{od}, \texttt{while}, \texttt{read}, \texttt{write}. + +Примеры идентификаторов: \texttt{a}, \texttt{X}, \texttt{GCD}, \texttt{Milan23}. +Цепочки символов, недопустимые РІ качестве идентификаторов: \texttt{12a} (первый +СЃРёРјРІРѕР» РЅРµ является Р±СѓРєРІРѕР№), \texttt{Begin} (цепочка символов совпадает СЃ +ключевым словом), \texttt{a\_1} (цепочка содержит СЃРёРјРІРѕР» подчеркивания). + +\subsection{Арифметические выражения} + +\begin{grammar} + ::= \{ \} + + ::= \{ \} + + ::= | | `(' `)' +\end{grammar} + +Арифметические выражения строятся РїРѕ традиционным для языков программирования +правилам. Элементами арифметических выражений РјРѕРіСѓС‚ быть константы, +идентификаторы, знаки арифметических операций `\texttt{+}' (сложение), +`\texttt{-}' (вычитание), `\texttt{*}' (умножение), `\texttt{/}' +(деление), СЃРєРѕР±РєРё Рё ключевое слово \texttt{read}, которое обозначает операцию +чтения числа СЃРѕ стандартного РІРІРѕРґР°. + +Примеры правильных выражений: \texttt{12 + 4}, \texttt{i}, \texttt{(x+1)*y}, +\texttt{2*x+1}, \texttt{read}, \texttt{read * (x - read)}. + +Операции `\texttt{*}' Рё `\texttt{/}' имеют более высокий приоритет, чем +операции `\texttt{+}' Рё `\texttt{-}'. Р’СЃРµ эти операции левоассоциативны. + +Значения арифметических выражений вычисляются слева направо СЃ учетом приоритета +операций. РџРѕСЂСЏРґРѕРє вычисления важен РёР·-Р·Р° присутствия операции \texttt{read}, +благодаря которой вычисление значения выражения имеет побочный эффект. + +\subsection{Печать чисел РЅР° стандартный вывод} + +\begin{grammar} + ::= `write' `(' `)' +\end{grammar} + +Печать чисел осуществляется СЃ помощью оператора \texttt{write}, аргументом +которого является произвольное арифметическое выражение. Примеры использования +оператора \texttt{write}: \texttt{write(5)}, +\texttt{write(n+7)}, \texttt{write((2+read)*3)}, \texttt{write(read)}. + +\subsection{Оператор присваивания} + +\begin{grammar} + ::= `:=' +\end{grammar} + +РџСЂРё выполнении оператора присваивания сначала вычисляется значение выражения, +записанного РІ его правой части. Затем результат записывается РІ ячейку памяти, +соответствующую переменной РІ левой части оператора присваивания. + +Последовательность символов `\texttt{:=}' является неделимой Рё РЅРµ может +содержать пробелов между символами `\texttt{:}' Рё `\texttt{=}'. + +Примеры корректных операторов присваивания: \texttt{a := b + 1}, \texttt{c := +read}. + +\subsection{Условный оператор} + +\begin{grammar} + ::= `if' `then' [`else' ] `fi' + + ::= + + ::= `=' | `!=' | `<' | `<=' | `>' | `>=' +\end{grammar} + +Условный оператор включает: +\begin{enumerate} +\item условие, которое представляет СЃРѕР±РѕР№ проверку РЅР° равенство или неравенство +РґРІСѓС… арифметических выражений, +\item последовательность операторов, которая должна быть выполнена, если условие +истинно (блок \texttt{then}), +\item необязательную последовательность операторов, которая должна быть +выполнена, если условие ложно (блок \texttt{else}). +\end{enumerate} + +Проверка условия $a ? b$, РіРґРµ $a$ Рё $b$ --- арифметические выражения, Р° <<$?$>> +--- РѕРґРёРЅ РёР· операторов сравнения, производится следующим образом: +\begin{enumerate} +\item вычисляется значение выражения $a$; +\item вычисляется значение выражения $b$; +\item проверяется выполнение условия. +\end{enumerate} + +Поддерживаются следующие отношения: `\texttt{=}' (<<равно>>), `\texttt{!=}' +(<<РЅРµ равно>>), `\texttt{<}' (<<меньше>>), `\texttt{<=}' (<<меньше или равно>>), +`\texttt{>}' (<<больше>>), `\texttt{>=}' (<<больше или равно>>). + +Условный оператор завершается ключевым словом \texttt{fi}. РћРЅРѕ используется, +чтобы избежать известной проблемы <<висячего else>>, которая встречается, РІ +частности, РІ языках C, C++ Рё Java. Наличие <<закрывающей СЃРєРѕР±РєРё>> \texttt{fi} +позволяет однозначно интерпретировать вложенные условные операторы. + +Примеры использования условного оператора приведены РЅР° рисунках~\ref{ifthen} Рё +\ref{ifthenelse}. РћР±Рµ эти программы считывают СЃРѕ стандартного РІРІРѕРґР° РґРІР° числа. +Программа РЅР° СЂРёСЃСѓРЅРєРµ~\ref{ifthen} печатает наибольшее РёР· РґРІСѓС… чисел. Программа +РЅР° СЂРёСЃСѓРЅРєРµ~\ref{ifthenelse} печатает числа РІ РїРѕСЂСЏРґРєРµ возрастания. + +\begin{figure} +\begin{lstlisting} +begin + x := read; + y := read; + max := x; + if y > max then + max := y + fi; + write (max) +end +\end{lstlisting} +\label{ifthen} +\caption{Пример условного оператора \texttt{if..then..fi}} +\end{figure} + +\begin{figure} +\begin{lstlisting} +begin + x := read; + y := read; + if x <= y then + write (x); + write (y) + else + write (y); + write (x) + fi +end +\end{lstlisting} +\label{ifthenelse} +\caption{Пример условного оператора \texttt{if..then..else..fi}} +\end{figure} + +\subsection{Цикл СЃ предусловием} + +\begin{grammar} + ::= `while' `do' `od' + + ::= + + ::= `=' | `!=' | `<' | `<=' | `>' | `>=' +\end{grammar} + +РџСЂРё выполнении цикла СЃ предусловием сначала проверяется, истинно ли условие. +Если РѕРЅРѕ истинно, последовательно выполняются операторы, составляющие тело +цикла. После того, как последний оператор будет выполнен, управление СЃРЅРѕРІР° +возвращается Рє проверке условия. Если условие оказывается ложным, выполнение +цикла завершается. Вычисление выражений, необходимых для проверки условия, +производится так Р¶Рµ, как Рё РїСЂРё выполнении условного оператора. + +Пример программы, использующей цикл, приведен РЅР° СЂРёСЃСѓРЅРєРµ~\ref{while}. Эта +программа считывает СЃРѕ стандартного РІРІРѕРґР° число Рё печатает его факториал. + +\begin{figure} +\begin{lstlisting} +begin + n := read; + factorial := 1; + x := 1; + while x <= n do + factorial := factorial * x; + x := x + 1 + od; + write (factorial) +end +\end{lstlisting} +\label{while} +\caption{Пример цикла СЃ предусловием} +\end{figure} + +\section{Рспользование компилятора} + +Компилятор \textsc{CMilan} преобразует программы РЅР° языке Милан РІ +последовательность команд виртуальной машины Милана. Общее описание виртуальной +машины РјРѕР¶РЅРѕ найти РІ учебнике~\cite{karpov05}, Р° более детальное +описание --- или РІ документации, прилагаемой Рє исходным текстам виртуальной +машины. + +Рсполняемый файл компилятора называется \texttt{cmilan} (РІ операционных системах +семейства Unix) или \texttt{cmilan.exe} (РІ Windows). Компилятор имеет интерфейс +командной строки. Чтобы скомпилировать программу, записанную РІ файле +<>, РЅСѓР¶РЅРѕ выполнить команду <<\texttt{cmilan program.mil}>>. +Результатом работы компилятора является либо последовательность команд для +виртуальной машины Милана, которая печатается РЅР° стандарный вывод, либо набор +сообщений Рѕ синтаксических ошибках, которые выводятся РІ стандартный поток +ошибок. + +РџСЂРё вызове программы \texttt{cmilan} без параметров компилятор печатает краткую +информацию Рѕ РїРѕСЂСЏРґРєРµ его вызова. + +Чтобы сохранить генерируемую компилятором программу для виртуальной машины РІ +файл, достаточно перенаправить РІ этот файл стандартный поток вывода. + +РќР° СЂРёСЃСѓРЅРєРµ~\ref{cmilan-usage} приведен пример сеанса работы СЃ компилятором. + +\begin{figure} +\begin{verbatim} +bash$ cat factorial.mil +BEGIN + n := READ; + factorial := 1; + i := 1; + WHILE i <= n DO + factorial := factorial * i; + i := i + 1 + OD; + WRITE(factorial) +END +bash$ cmilan factorial.mil > factorial.out +bash$ milanvm factorial.out +Reading input from factorial.out +> 5 +120 +\end{verbatim} +\label{cmilan-usage} +\caption{Пример использования компилятора \textsc{CMilan}} +\end{figure} + +\subsection{РЎР±РѕСЂРєР° компилятора РІ Unix} + +Для СЃР±РѕСЂРєРё компилятора РІ операционных системах семейства Unix (РІ частности, +GNU/Linux Рё FreeBSD) необходим компилятор C++, РІ качестве которого рекомендуется +использовать GCC, Рё GNU Make. Для СЃР±РѕСЂРєРё компилятора достаточно перейти РІ +каталог \texttt{src}, РІ котором расположены исходные тексты компилятора +\textsc{CMilan}, Рё выполнить команду \texttt{make}. + +\subsection{РЎР±РѕСЂРєР° компилятора РІ Windows} + +Для СЃР±РѕСЂРєРё компилятора \textsc{CMilan} РІ Windows РјРѕР¶РЅРѕ использовать компилятор +GCC или Microsoft Visual Studio. РџСЂРё использовании GCC (Cygwin, MinGW) СЃР±РѕСЂРєР° +производится так Р¶Рµ, как Рё РІ Unix. Для СЃР±РѕСЂРєРё компилятора СЃ помощью Visual +Studio 2010 РІ дистрибутив компилятора включены файлы проекта (каталог +\texttt{src\\cmilan\_vs2011}). Если необходимо использовать РґСЂСѓРіРёРµ версии Visual +Studio, достаточно создать пустой проект консольного приложения Win32 Рё добавить +РІ проект существующие исходные тексты РёР· каталога \texttt{src}. + +\section{Устройство компилятора} + +\subsection{Архитектура компилятора} +Компилятор \textsc{CMilan} включает три компонента: +\begin{enumerate} +\item лексический анализатор; +\item синтаксический анализатор; +\item генератор команд виртуальной машины Милана. +\end{enumerate} + +Лексический анализатор посимвольно читает РёР· РІС…РѕРґРЅРѕРіРѕ потока текст программы Рё преобразует +РіСЂСѓРїРїС‹ символов РІ лексемы (терминальные символы грамматики языка Милан). РџСЂРё +этом РѕРЅ отслеживает номер текущей строки, который используется синтаксическим +анализатором РїСЂРё формировании сообщений РѕР± ошибках. Также лексический анализатор +удаляет пробельные символы Рё комментарии. РџСЂРё формировании лексем анализатор +идентифицирует ключевые слова Рё последовательности символов (например, оператор +присваивания), Р° также определяет значения числовых констант Рё имена переменных. +Эти значения становятся значениями атрибутов, связанных СЃ лексемами. + +Синтаксический анализатор читает сформированную лексическим анализатором +последовательность лексем Рё проверяет ее соответствие грамматике языка Милан. +Для этого используется метод рекурсивного СЃРїСѓСЃРєР°. Если РІ процессе +синтаксического анализа обнаруживается ошибка, анализатор формирует сообщение РѕР± +ошибке, включающее сведения РѕР± ошибке Рё номер строки, РІ которой РѕРЅР° возникла. +Р’ процессе анализа программы синтаксический анализатор генерирует набор машинных +команд, соответствующие каждой конструкции языка. + +Генератор РєРѕРґР° представляет СЃРѕР±РѕР№ служебный компонент, ответственный Р·Р° +формирование внешнего представления генерируемого РєРѕРґР°. Генератор поддерживает +буфер команд Рё предоставляет синтаксическому анализатору набор функций, +позволяющий записать указанную команду РїРѕ определенному адресу. После того, как +синтаксический анализатор заканчивает формирование программы, генератор РєРѕРґР° +используется для печати РЅР° стандартный вывод отсортированной РїРѕ возрастанию +адресов последовательности инструкций. Рспользование генератора РєРѕРґР° несколько +упрощает устройство компилятора, поскольку синтаксический анализатор может +генерировать команды РЅРµ РІ РїРѕСЂСЏРґРєРµ РёС… следования РІ программе, Р° РїРѕ мере получения +всей необходимой информации для РёС… формирования. Это особенно важно РїСЂРё +трансляции таких инструкций, как условные операторы или циклы. + +Р’СЃРµ три компонента объединяются <<драйвером>> --- управляющей программой +компилятора. Драйвер анализирует аргументы командной строки, инициализирует +синтаксический анализатор Рё вызывает его метод \texttt{parse()}, запуская +процесс трансляции. + +\textsc{CMilan} является примером простейшего РѕРґРЅРѕРїСЂРѕС…РѕРґРЅРѕРіРѕ компилятора, +РІ котором синтаксический анализ Рё генерация РєРѕРґР° выполняются совместно. РџСЂРё этом +компилятор никак РЅРµ оптимизирует РєРѕРґ. Реальные компиляторы +обычно выполняют трансляцию Рё оптимизацию РєРѕРґР° РІ несколько РїСЂРѕС…РѕРґРѕРІ, используя +несколько РІРёРґРѕРІ внутреннего представления программы. Сведения РѕР± архитектуре +таких компиляторов РјРѕР¶РЅРѕ найти, РІ частности, РІ классической <<РєРЅРёРіРµ +дракона>>~\cite{dragonbook11}. Р’ случае \textsc{CMilan}, тем РЅРµ менее, +предпочтение было отдано РЅРµ качеству генерируемого РєРѕРґР°, Р° простоте реализации Рё +легкости расширения. + +\subsection{Генератор РєРѕРґР°} + +РћСЃРЅРѕРІРЅРѕР№ задачей генератора РєРѕРґР° является хранение Рё заполнение буфера +инструкций последовательностью команд для виртуальной машины Милана. Генератор +РєРѕРґР° РЅРµ отвечает Р·Р° правильность этой последовательности Рё РЅРµ выполняет никаких +семантических преобразований. Тем РЅРµ менее, генератор РєРѕРґР° вполне РјРѕРі Р±С‹ быть +расширен для того, чтобы выполнять простые оптимизации РЅР° СѓСЂРѕРІРЅРµ машинных +команд. + +Генератор РєРѕРґР° описан РІ файлах \texttt{codegen.h} Рё \texttt{codegen.cpp}. Его +реализация состоит РёР· РґРІСѓС… классов. Класс \texttt{Command} описывает машинные +инструкций Рё отвечает Р·Р° РёС… вывод. Р’ классе Codegen реализованы функции добавления +инструкций РІ буфер, получения текущего адреса РІ буфере, резервирования ячейки +для инструкции, которая должна быть добавлена РІ РєРѕРґ позднее, Рё печати +последовательности инструкций РёР· буфера РЅР° стандартный вывод. + +Приведем краткое описание методов генератора РєРѕРґР°. +\begin{itemize} +\item \texttt{void Command::print(int address, ostream\& os)} + + Печать инструкции СЃ указанием адреса \texttt{address} РІ поток вывода \texttt{os}. + +\item \texttt{void CodeGen::emit(Instruction instruction)} + + Добавление инструкции \texttt{instruction} без аргументов РІ конец буфера. + +\item \texttt{void CodeGen::emit(Instruction instruction, int arg)} + + Добавление инструкции \texttt{instruction} СЃ аргументом \texttt{arg} РІ конец буфера. + +\item \texttt{void CodeGen::emitAt(int address, Instruction instruction)} + + Запись инструкции \texttt{instruction} без аргументов РІ буфер СЃРѕ смещением + \texttt{address}. + +\item \texttt{void CodeGen::emitAt(int address, Instruction instruction, int +arg)} + + Запись инструкции \texttt{instruction} СЃ аргументом \texttt{arg} РІ буфер + СЃРѕ смещением \texttt{address} + +\item \texttt{int CodeGen::getCurrentAddress()} + + Возврат адреса, РїРѕ которому будет записана очередная инструкция. + +\item \texttt{int CodeGen::reserve()} + + Резервирование ячейки памяти для инструкции. Метод добавляет РІ конец + буфера инструкцию \texttt{NOP} Рё возвращает ее адрес. + +\item \texttt{void CodeGen::flush()} + + Вывод последовательности инструкций РІ выходной поток. +\end{itemize} + +\subsection{Лексический анализатор} + +Лексический анализатор преобразует считываемые РёР· РІС…РѕРґРЅРѕРіРѕ потока символы РІ +лексемы языка Милан. Например, последовательность символов `\texttt{B}', +`\texttt{E}', `\texttt{G}', `\texttt{I}', `\texttt{N}' соответствует ключевому +слову `\texttt{begin}'. Каждой лексеме соответствует отдельный элемент +перечислимого типа \texttt{Token}. Р’ частности, ключевому слову `\texttt{begin}' +соответствует константа \texttt{T\_BEGIN}. РЎ некоторыми лексемами связана +дополнительная информация --- значение атрибута. Так, СЃ лексемой +\texttt{T\_NUMBER} (целочисленная константа) связано число, равное значению этой +константы, Р° СЃ лексемой \texttt{T\_IDENTIFIER} (идентификатор) --- строка, +содержащая РёРјСЏ переменной. + +Р’ таблице~\ref{lexemes} приведен полный СЃРїРёСЃРѕРє лексем Рё значений связанных СЃ РЅРёРјРё +атрибутов. + +\begin{table} +\begin{center} +\begin{tabular}{|l|l|p{6cm}|} +\hline +\hline +РРјСЏ лексемы & Значение & Атрибут \\ +\hline +\hline +\texttt{T\_EOF} & Конец текстового потока & \\ +\hline +\texttt{T\_ILLEGAL} & Недопустимый СЃРёРјРІРѕР» & \\ +\hline +\texttt{T\_IDENTIFIER}& Рдентификатор & РРјСЏ переменной \\ +\hline +\texttt{T\_NUMBER} & Константа & Значение константы \\ +\hline +\texttt{T\_BEGIN} & Ключевое слово `\texttt{begin}' & \\ +\hline +\texttt{T\_END} & Ключевое слово `\texttt{end}' & \\ +\hline +\texttt{T\_IF} & Ключевое слово `\texttt{if}' & \\ +\hline +\texttt{T\_THEN} & Ключевое слово `\texttt{then}' & \\ +\hline +\texttt{T\_ELSE} & Ключевое слово `\texttt{else}' & \\ +\hline +\texttt{T\_FI} & Ключевое слово `\texttt{fi}' & \\ +\hline +\texttt{T\_WHILE} & Ключевое слово `\texttt{while}' & \\ +\hline +\texttt{T\_DO} & Ключевое слово `\texttt{do}' & \\ +\hline +\texttt{T\_OD} & Ключевое слово `\texttt{od}' & \\ +\hline +\texttt{T\_WRITE} & Ключевое слово `\texttt{write}' & \\ +\hline +\texttt{T\_READ} & Ключевое слово `\texttt{read}' & \\ +\hline +\texttt{T\_ASSIGN} & Оператор `\texttt{:=}' & \\ +\hline +\texttt{T\_ADDOP} & Операция типа сложения & +\texttt{A\_PLUS}~(`\texttt{+}'), \texttt{A\_MINUS}~(`\texttt{-}') \\ +\hline +\texttt{T\_MULOP} & Операция типа умножения & +\texttt{A\_MULTIPLY}~(`\texttt{*}'), \texttt{A\_DIVIDE}~(`\texttt{/}') \\ +\hline +\texttt{T\_CMP} & Оператор отношения & +\texttt{C\_EQ}~(`\texttt{=}'), \texttt{C\_NE}~(`\texttt{!=}'), +\texttt{C\_LT}~(`\texttt{<}'), \texttt{C\_LE}~(`\texttt{<=}'), +\texttt{C\_GT}~(`\texttt{>}'), \texttt{C\_GE}~(`\texttt{=}') \\ +\hline +\texttt{T\_LPAREN} & Открывающая СЃРєРѕР±РєР° & \\ +\hline +\texttt{T\_RPAREN} & Закрывающая СЃРєРѕР±РєР° & \\ +\hline +\texttt{T\_SEMICOLON} & `\texttt{;}' & \\ +\hline +\hline +\end{tabular} +\end{center} +\caption{Лексемы языка Милан} +\label{lexemes} +\end{table} + +Р’СЃРµ ключевые слова перечислены РІ ассоциативном массиве \texttt{keywords\_}. РџСЂРё +этом ключом является строка, соответствующая ключевому слову РІ нижнем регистре, +Р° значением --- соответствующая лексема. РЎ помощью массива \texttt{tokenNames\_} +каждой лексеме сопоставлено ее строковое внешнее представление, которое +используется РїСЂРё формировании сообщений РѕР± ошибках. Последовательность +символов, РЅРµ соответствующая РЅРё РѕРґРЅРѕР№ РёР· лексем, считается ошибочной. Р’ этом +случае лексический анализатор возвращает значение \texttt{T\_ILLEGAL}. + +Рсходный текст лексического анализатора находится РІ файлах \texttt{scanner.h} Рё +\texttt{scanner.cpp}. Алгоритм лексического анализа реализован РІ классе +\texttt{Scanner}. РћРЅ содержит следующие открытые методы: + +\begin{itemize} +\item \texttt{Token token()} + + Получение текущей лексемы. РћРґРЅР° Рё та Р¶Рµ лексема может быть прочитана + многократно. + +\item \texttt{void nextToken()} + + Переход Рє следующей лексеме. + +\item \texttt{int getIntValue()} + + Получение целочисленного атрибута текущей лексемы. Р’ базовой версии Милана + этот метод используется только для получения значений целочисленных + констант. + +\item \texttt{string getStringValue()} + + Получение строкового атрибута текущей лексемы. Р’ базовой версии Милана + этот метод используется для получения имен идентификаторов. + +\item \texttt{Cmp getCmpValue()} + + Получение РєРѕРґР° операции сравнения текущей лексемы (используется только + вместе СЃ лексемой \texttt{T\_CMP}). + +\item \texttt{Arithmetic getArithmeticValue()} + + Получение РєРѕРґР° арифметической операции (используется вместе СЃ лексемами + \texttt{T\_ADDOP} Рё \texttt{T\_MULOP}). + +\item \texttt{const int getLineNumber()} + + Получение номера текущей строки РІ РёСЃС…РѕРґРЅРѕРј файле (используется РїСЂРё + формировании сообщений РѕР± ошибках). +\end{itemize} + +Поля класса описывают состояние лексического анализатора: +\begin{itemize} +\item \texttt{const string fileName\_} + + РРјСЏ РІС…РѕРґРЅРѕРіРѕ файла. + +\item \texttt{int lineNumber\_} + + Номер текущей строки РІ анализируемой программе. + +\item \texttt{Token token\_} + + Текущая лексема. + +\item \texttt{int intValue\_} + + Целочисленный атрибут лексемы. + +\item \texttt{string stringValue\_} + + Строковый атрибут лексемы. + +\item \texttt{Cmp cmpValue\_} + + РљРѕРґ оператора сравнения. + +\item \texttt{Arithmetic arithmeticValue\_} + + РљРѕРґ арифметической операции. + +\item \texttt{map keywords\_} + + Ассоциативный массив, описывающий ключевые слова языка Милан. Рспользуется + РїСЂРё обнаружении цепочки символов, которая может быть как идентификатором, + так Рё ключевым словом. + +\item \texttt{ifstream input\_} + + Р’С…РѕРґРЅРѕР№ поток для чтения РёР· файла. + +\item \texttt{char ch\_} + + Очередной СЃРёРјРІРѕР» программы. +\end{itemize} + +Закрытые методы класса (служебные функции): +\begin{itemize} +\item \texttt{bool isIdentifierStart(char c)} + + Метод возвращает значение \texttt{true}, если СЃРёРјРІРѕР» \texttt{c} может быть + первым символом идентификатора (РІ базовой версии языка Милан это означает, + что СЃРёРјРІРѕР» является Р±СѓРєРІРѕР№ латинского алфавита). + +\item \texttt{bool isIdentifierBody(char c)} + + Метод возвращает значение \texttt{true}, если СЃРёРјРІРѕР» \texttt{c} может + быть частью идентификатора. Р’ базовой версии языка Милан СЌС‚ означает, что + СЃРёРјРІРѕР» является Р±СѓРєРІРѕР№ латинского алфавита или цифрой. + +\item \texttt{void skipSpace()} + + РџСЂРѕРїСѓСЃРє всех пробельных символов (символов пробела, табуляции, перевода + строки). РџСЂРё чтении символа перевода строки увеличивается номер текущей + строки \texttt{lineNumber\_}. + +\item \texttt{void nextChar()} + + Переход Рє следующему символу программы. +\end{itemize} + +Основная часть алгоритма лексического анализа реализована РІ методе +\texttt{nextToken}. Для того, чтобы перейти Рє следующей лексеме, выполняется +следующая последовательность действий, + +Прежде всего необходимо удалить пробелы Рё комментарии. Признаком начала +комментария является последовательность символов `\texttt{/*}'. РџСЂРё обнаружении +символа `\texttt{/}' необходимо проверить следующий Р·Р° РЅРёРј СЃРёРјРІРѕР». Если РѕРЅ РЅРµ +совпадает СЃ `\texttt{*}', значит, был найден оператор деления. Р’ этом случае +переменной \texttt{token\_} присваивается значение \texttt{T\_MULOP}, Р° атрибуту +\texttt{arithmeticValue\_} --- значение \texttt{A\_DIVIDE}. Если Р·Р° символом +`\texttt{/}' непосредственно следует `\texttt{*}', лексический анализатор +пропускает РІСЃРµ символы, РїРѕРєР° РЅРµ встретит закрывающую комментарий +последовательность `\texttt{*/}' или конец файла. После того, как был найден +признак конца комментария, еще раз вызывается функция \texttt{skipSpace}. +Операция удаления комментариев повторяется многократно, РїРѕРєР° очередной +непробельный СЃРёРјРІРѕР» РЅРµ окажется отличным РѕС‚ символа `\texttt{/}'. Если РІ +процессе удаления пробелов или комментариев был встречен конец файла, очередной +лексемой считается \texttt{T\_EOF}. + +После удаления пробелов Рё комментариев РїСЂРѕРёСЃС…РѕРґРёС‚ анализ очередного символа. РћРЅ +выполняется РїРѕ следующим правилам. +\begin{enumerate} +\item Если СЃРёРјРІРѕР» является цифрой, то очередная лексема --- целочисленная константа +(\texttt{T\_NUMBER}). Лексический анализатор считывает РёР· РІС…РѕРґРЅРѕРіРѕ потока эту +Рё РІСЃРµ следующие Р·Р° ней цифры, преобразуя полученную последовательность РІ целое +число. Это число становится значением атрибута \texttt{intValue\_}. + +\item Если СЃРёРјРІРѕР» может быть началом идентификатора, РёР· потока считываются РІСЃРµ +последующие символы, которые РјРѕРіСѓС‚ быть частью идентификатора. Полученная +последовательность проверяется РЅР° совпадение СЃ ключевым словом. Р’ случае +совпадения очередной лексемой считается лексема, соответствующая этому ключевому +слову. Если цепочка символов РЅРµ совпала РЅРё СЃ РѕРґРЅРёРј ключевым словом, очередная +лексема считается идентификатором (\texttt{T\_IDENTIFIER}), Р° сама цепочка +становится значением строкового атрибута \texttt{stringValue\_}. + +\item Если СЃРёРјРІРѕР» равен `\texttt{:}', лексический анализатор считывает следующий +СЃРёРјРІРѕР» Рё проверяет, что РѕРЅ равен `\texttt{=}'. Р’ этом случае возвращается +лексема \texttt{T\_ASSIGN}. Если следом Р·Р° `\texttt{:}' идет любой РґСЂСѓРіРѕР№ +СЃРёРјРІРѕР», лексема считается ошибочной (\texttt{T\_ILLEGAL}). + +\item Если СЃРёРјРІРѕР» равен `\texttt{!}', производится аналогичная проверка РЅР° +равенство следующего символа `\texttt{=}'. Р’ случае успеха текущей лексемой +становится лексема \texttt{T\_CMP}, Р° атрибут \texttt{cmpValue\_} принимает +значение \texttt{T\_NE}. + +\item Если СЃРёРјРІРѕР» равен `\texttt{<}', `\texttt{>}' или `\texttt{=}', текущей +лексемой становится \texttt{T\_CMP}. Чтобы определить значение атрибута +\texttt{cmpValue\_}, лексический анализатор может прочитать еще РѕРґРёРЅ СЃРёРјРІРѕР» для +того, чтобы отличить оператор `\texttt{<}' РѕС‚ оператора `\texttt{>}', Р° оператор +`\texttt{>}' РѕС‚ оператора `\texttt{>=}'. + +\item Если СЃРёРјРІРѕР» равен `\texttt{+}' или `\texttt{-}', переменная +\texttt{token\_} принимает значение \texttt{T\_ADDOP}, РїСЂРё этом соответствующим +образом устанавливается значение атрибута \texttt{arithmeticValue\_}. Аналогично +обрабатываются СЃРёРјРІРѕР» `\texttt{*}' (лексема \texttt{T\_MULOP}). Оператор деления +обрабатывать таким Р¶Рµ образом РЅРµ РЅСѓР¶РЅРѕ, поскольку РѕРЅ обнаруживается РІ С…РѕРґРµ +удаления комментариев. + +\item Если СЃРёРјРІРѕР» совпадает СЃ `\texttt{;}', `\texttt{(}', `\texttt{)}', +очередная лексема устанавливается РІ соответствующее символу значение. +\end{enumerate} + +\subsection{Синтаксический анализатор} + +Задачами синтаксического анализатора является проверка соответствия программы +грамматике языка Милан (СЂРёСЃСѓРЅРѕРє~\ref{milan-grammar}) Рё формирование РєРѕРґР° для +виртуальной машины Милана РІ соответствии СЃРѕ структурой программы. Синтаксический +анализ выполняется методом рекурсивного СЃРїСѓСЃРєР°. Каждому нетерминальному символу +грамматики сопоставлен метод, выполняющий проверку соответствия +последовательности лексем РѕРґРЅРѕРјСѓ РёР· тех правил грамматики, РІ левой части которых +стоит данный нетерминальный СЃРёРјРІРѕР». Семантические действия (генерация РєРѕРґР°) +встроены РІ РєРѕРґ метода. + +Рсходный текст синтаксического анализатора находится РІ файлах \texttt{parser.h} +Рё \texttt{parser.cpp}. Алгоритм синтаксического анализа реализован РІ классе +\texttt{Parser}. Конструктор класса РІ качестве аргумента принимает РёРјСЏ файла, РІ +котором находится анализируемый текст, Рё создает экземпляры лексического +анализатора Рё генератора РєРѕРґР°. + +Синтаксический анализатор предоставляет РѕРґРёРЅ открытый метод \texttt{void parse()}, +который используется для того, чтобы начать процесс анализа. + +Состояние анализатора описывается следующими полями: +\begin{itemize} +\item \texttt{Scanner* scanner\_} + + Экземпляр лексического анализатора. + +\item \texttt{CodeGen* codegen\_} + + Экземпляр генератора РєРѕРґР°. + +\item \texttt{std::ostream\& output\_} + + Выходной поток, РІ который должны быть выведены инструкции программы. + Базовая версия компилятора Милан использует РІ качестве выходного потока + стандартный вывод (\texttt{std::cout}). + +\item \texttt{bool error\_} + + Признак ошибки РІ тексте программы. Если \texttt{error\_} принимает + значение <<истина>>, генерируемый машинный РєРѕРґ РЅРµ выводится. + +\item \texttt{map variables\_} + + Таблица имен, найденных РІ программе. РћРЅР° сопоставляет каждой переменной ее + адрес РІ памяти виртуальной машины. Поскольку базовая версия языка Милан РЅРµ + содержит вложенных блоков, процедур или функций, таблица имен представляет + СЃРѕР±РѕР№ простой ассоциативный массив. + +\item \texttt{int lastVar\_} + + Адрес последней найденной переменной. +\end{itemize} + +Синтаксический анализатор включает СЂСЏРґ вспомогательных функций (закрытые методы +класса). + +\begin{itemize} +\item \texttt{bool see(Token t)} + + Сравнение текущей лексемы СЃ образцом. Текущая позиция РІ потоке лексем РЅРµ + изменяется. + +\item \texttt{bool match(Token t)} + + Проверка совпадения текущей лексемы СЃ образцом. Если лексема Рё образец + совпадают, лексема изымается РёР· потока. + +\item \texttt{void mustBe(Token t)} + + Проверка совпадения текущей лексемы СЃ образцом. Если лексема Рё образец + совпадают, лексема изымается РёР· потока. Р’ противном случае формируется + сообщение РѕР± ошибке, Р° программа считается некорректной. + +\item \texttt{void next()} + + Переход Рє следующей лексеме. + +\item \texttt{void reportError(const string\& message)} + + Формирование сообщения РѕР± ошибке. Каждое сообщение включает текст + \texttt{message} Рё номер строки, РІ которой обнаружена ошибка. + +\item \texttt{void recover(Token t)} + + Восстановление после ошибки. Рспользуется примитивный алгоритм: если + очередная лексема РЅРµ совпадает СЃ ожидаемой, анализатор пропускает РІСЃРµ + последующие лексемы, РїРѕРєР° РЅРµ встретит ожидаемую лексему или + конец файла. Хотя такой метод восстановления РЅРµ отличается точностью, РѕРЅ, + тем РЅРµ менее, позволяет продолжить анализ Рё, РІРѕР·РјРѕР¶РЅРѕ, найти ошибки РІ + оставшейся части программы. + +\item \texttt{int findOrAddVariable(const string\&)} + + РџРѕРёСЃРє имени переменной РІ таблице имен. Если РёРјСЏ найдено, метод возвращает + адрес переменной, РІ противном случае РёРјСЏ добавляется РІ таблицу имен, Рё для + соответствующей переменной резервируется новый адрес. +\end{itemize} + +РљСЂРѕРјРµ служебных методов, класс \texttt{Parser} содержит закрытые методы +\texttt{void program()}, \texttt{void statementList()}, \texttt{void +statement()}, \texttt{void expression()}, \texttt{void term()}, \texttt{void +factor()}, \texttt{void relation()}, которые соответствуют нетерминальным +символам грамматики. Эти методы РЅРµ возвращают значений Рё РЅРµ принимают +аргументов, поскольку СЃ нетерминальными символами РЅРµ связаны явные атрибуты: РІСЃРµ +семантические действия, которые производятся РІРѕ время анализа программы, +модифицируют буфер общего для всех методов генератора РєРѕРґР°. + +\subsubsection{Распознавание операторов} + +Продемонстрируем алгоритм работы синтаксического анализатора РЅР° примере анализа +операторов (метод \texttt{statement}). + +Р’ соответствии СЃ грамматикой языка Милан, РІ качестве оператора может выступать +оператор присваивания, условный оператор \texttt{if}, оператор цикла +\texttt{while} или оператор печати \texttt{write}. Для выбора РЅСѓР¶РЅРѕР№ +альтернативы достаточно прочитать первую лексему оператора. + +Если очередная лексема равна \texttt{T\_IDENTIFIER}, синтаксический анализатор +имеет дело СЃ оператором присваивания. РћРЅ считывает РёРјСЏ переменной, стоящей РІ +левой части присваивания, Рё определяет ее адрес. Затем анализатор проверяет, что +следующая лексема совпадает СЃ \texttt{T\_ASSIGN}. После знака `\texttt{:=}' РІ +программе должно следовать арифметическое выражение, поэтому анализатор вызывает +метод \texttt{expression()}. Этот метод проверяет правильность арифметического +выражения Рё генерирует последовательность команд для его вычисления. Р’ +результате выполнены этой последовательности РЅР° вершине стека будет находиться +значение выражения. Чтобы выполнить присваивание, достаточно записать значение СЃ +вершины стека РІ память РїРѕ адресу переменной РІ левой части оператора +присваивания. Для этого после вызова \texttt{expression()} РЅСѓР¶РЅРѕ добавить РІ +буфер команд инструкцию \texttt{STORE}, аргументом которой будет запомненный +ранее адрес переменной. + +Если очередная лексема равна \texttt{T\_IF}, анализатор должен начать разбор +условного оператора. Сначала РѕРЅ вызывает метод \texttt{relation()}, проверяя, +что после лексемы \texttt{T\_IF} следует правильное сравнение РґРІСѓС… выражений. +Метод \texttt{relation()} генерирует РєРѕРґ, вычисляющий Рё сравнивающий РґРІР° +выражения. РџСЂРё выполнении этого РєРѕРґР° РЅР° вершине стека останется значение $1$, +если условие выполнено, Рё $0$ РІ противном случае. Если условие РЅРµ выполнено, +должен произойти переход Рє СЃРїРёСЃРєСѓ операторов блока \texttt{else} или, если этого +блока нет, РїРѕ адресу следующей Р·Р° условным оператором инструкции. Однако этот +адрес еще РЅРµ известен синтаксическому анализатору. Чтобы решить эту проблему, +применяется так называемый <<метод обратных поправок>>~\cite{dragonbook11}. +Анализатор резервирует место для условного перехода \texttt{JUMP\_NO} Рё +запоминает адрес этой инструкции РІ переменной \texttt{jumpNoAddress}, после чего +переходит Рє дальнейшему анализу условного оператора. + +Следом Р·Р° условием РІ тексте программы должна находиться лексема +\texttt{T\_THEN}. Если РѕРЅР° обнаружена, анализатор переходит Рє следующей лексеме +Рё вызывает метод \texttt{statementList()}, который анализирует СЃРїРёСЃРѕРє операторов +Рё генерирует для РЅРёС… исполняемый РєРѕРґ. Дальнейшие действия зависят РѕС‚ того, +присутствует ли РІ условном операторе ветвь \texttt{else}. Если следующая лексема +равна \texttt{T\_ELSE}, синтаксический анализатор должен сгенерировать +инструкцию \texttt{JUMP} для выхода РёР· условного оператора, после чего +приступить Рє анализу блока \texttt{else}. Если условный оператор РЅРµ содержит +блока \texttt{else}, инструкция безусловного перехода РІ конце блока +\texttt{then} РЅРµ РЅСѓР¶РЅР°. + +Генерация безусловного перехода также требует знания адреса, следующего Р·Р° +последней инструкцией условного оператора, поэтому анализатор СЃРЅРѕРІР° должен +зарезервировать ячейку памяти для команды перехода. Следующий Р·Р° этой ячейкой +адрес содержит первую команду блока \texttt{else}. Это именно тот адрес, РїРѕ +которому необходимо было выполнить переход РІ случае, если условие РЅРµ было +выполнено. Поскольку теперь этот адрес известен, синтаксический анализатор +генерирует инструкцию безусловного перехода Рё помещает ее РІ буфер команд РїРѕ +адресу, который записан РІ переменной \texttt{jumpNoAddress}. Р’ случае отсутствия +блока \texttt{else} поправка РїСЂРѕРёСЃС…РѕРґРёС‚ таким Р¶Рµ образом, РЅРѕ РІ качестве адреса +перехода просто используется следующий Р·Р° последней инструкцией блока +\texttt{then} адрес. После вызова функции \texttt{statementList}, которая +разбирает СЃРїРёСЃРѕРє операторов блока \texttt{else}, аналогично исправляется +зарезервированная инструкция безусловного перехода. + +Структура РєРѕРґР°, соответствующая условному оператору, приведена РЅР° +СЂРёСЃСѓРЅРєРµ~\ref{ifthenelse-code}. + +\begin{figure} +\begin{verbatim} + Вычисление выражений + ... + COMPARE operator + JUMP_NO elseLabel + Операторы блока THEN + ... + JUMP endLabel +elseLabel: Операторы блока ELSE + ... + endLabel: +\end{verbatim} +\caption{Структура исполняемого РєРѕРґР° условного оператора} +\label{ifthenelse-code} +\end{figure} + +Если очередная лексема равна \texttt{T\_WHILE}, синтаксическому анализатору +предстоит разобрать оператор цикла. Анализатор должен запомнить текущий адрес +команды, поскольку после каждой итерации цикла РїРѕ этому адресу РЅСѓР¶РЅРѕ будет +возвращаться. Затем анализатор вызывает метод \texttt{relation()}, чтобы +сгенерировать РєРѕРґ проверки условия. Если условие окажется ложным, РЅСѓР¶РЅРѕ будет +выполнить переход РЅР° следующий Р·Р° циклом оператор. Для этого синтаксический +анализатор резервирует ячейку памяти для команды \texttt{JUMP\_NO}. После этого +РѕРЅ проверяет наличие лексемы \texttt{T\_DO} Рё вызывает метод +\texttt{statementList()} для обработки тела цикла. Затем анализатор генерирует +инструкцию безусловного перехода назад, Рє началу проверки условия, Рё записывает +РІ зарезервированную ячейку инструкцию условного перехода РїРѕ известному теперь +адресу конца цикла. Для завершения анализа инструкции достаточно убедиться, что +очередная лексема равна ожидаемому значению \texttt{T\_OD}. Структура +исполняемого РєРѕРґР° для цикла приведена РЅР° СЂРёСЃСѓРЅРєРµ~\ref{while-code}. + +\begin{figure} +\begin{verbatim} +whileLabel: Вычисление выражений + ... + COMPARE operator + JUMP_NO endLabel + ... + Операторы тела цикла + ... + JUMP whileLabel + endLabel: +\end{verbatim} +\caption{Структура исполняемого РєРѕРґР° цикла СЃ предусловием} +\label{while-code} +\end{figure} + +Если очередная лексема равна \texttt{T\_WRITE}, необходимо проверить, что +следующая лексема равна \texttt{T\_LPAREN}, затем вызвать метод +\texttt{expression()} Рё проверить, что Р·Р° выражением РІ потоке следует лексема +\texttt{T\_RPAREN}. Поскольку РєРѕРґ, вычисляющий значение выражения, оставляет его +значение РЅР° вершине стека, для выполнения печати достаточно после вызова +\texttt{expression()} сгенерировать инструкцию \texttt{PRINT}. + +\begin{thebibliography}{9} +\addcontentsline{toc}{section}{РЎРїРёСЃРѕРє литературы} + +\bibitem{dragonbook11} + Рђ. РђС…Рѕ, Рњ. Лам, Р . Сети, Дж. Ульман, + \emph{Компиляторы: принципы, технологии Рё инструментарий}, 2-Рµ РёР·Рґ. + Рњ.: Вильямс, 2011. + +\bibitem{karpov05} + Р®.Р“. Карпов, + \emph{Теория Рё технология программирования. РћСЃРЅРѕРІС‹ построения трансляторов}. + РЎРџР±.: БХВ-Петербург, 2005. +\end{thebibliography} + +\end{document} + diff --git a/lab4/cmilan/src/Makefile b/lab4/cmilan/src/Makefile new file mode 100644 index 0000000..fe098cf --- /dev/null +++ b/lab4/cmilan/src/Makefile @@ -0,0 +1,23 @@ +CFLAGS = -Wall -W -Werror -O2 +LDFLAGS = + +HEADERS = scanner.h \ + parser.h \ + codegen.h + +OBJS = main.o \ + codegen.o \ + scanner.o \ + parser.o \ + +EXE = cmilan + +$(EXE): $(OBJS) $(HEADERS) + $(CXX) $(LDFLAGS) -o $@ $(OBJS) + +.cpp.o: + $(CXX) $(CFLAGS) -c $< -o $@ + +clean: + -@rm -f $(EXE) $(OBJS) + diff --git a/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.sln b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.sln new file mode 100644 index 0000000..78d63b7 --- /dev/null +++ b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.sln @@ -0,0 +1,20 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cmilan_vs2011", "cmilan_vs2011.vcxproj", "{1D542465-2019-4442-864E-DC785FA067A8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1D542465-2019-4442-864E-DC785FA067A8}.Debug|Win32.ActiveCfg = Debug|Win32 + {1D542465-2019-4442-864E-DC785FA067A8}.Debug|Win32.Build.0 = Debug|Win32 + {1D542465-2019-4442-864E-DC785FA067A8}.Release|Win32.ActiveCfg = Release|Win32 + {1D542465-2019-4442-864E-DC785FA067A8}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj new file mode 100644 index 0000000..6654c34 --- /dev/null +++ b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj @@ -0,0 +1,92 @@ +п»ї + + + + Debug + Win32 + + + Release + Win32 + + + + {1D542465-2019-4442-864E-DC785FA067A8} + Win32Proj + cmilan_vs2011 + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + cmilan + + + false + cmilan + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.filters b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.filters new file mode 100644 index 0000000..f1b7248 --- /dev/null +++ b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.filters @@ -0,0 +1,42 @@ +п»ї + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.user b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/lab4/cmilan/src/cmilan_vs2011/cmilan_vs2011.vcxproj.user @@ -0,0 +1,3 @@ +п»ї + + \ No newline at end of file diff --git a/lab4/cmilan/src/codegen.cpp b/lab4/cmilan/src/codegen.cpp new file mode 100644 index 0000000..24462e3 --- /dev/null +++ b/lab4/cmilan/src/codegen.cpp @@ -0,0 +1,129 @@ +#include "codegen.h" + +void Command::print(int address, ostream& os) +{ + os << address << ":\t"; + switch(instruction_) { + case NOP: + os << "NOP"; + break; + + case STOP: + os << "STOP"; + break; + + case LOAD: + os << "LOAD\t" << arg_; + break; + + case STORE: + os << "STORE\t" << arg_; + break; + + case BLOAD: + os << "BLOAD\t" << arg_; + break; + + case BSTORE: + os << "BSTORE\t" << arg_; + break; + + case PUSH: + os << "PUSH\t" << arg_; + break; + + case POP: + os << "POP"; + break; + + case DUP: + os << "DUP"; + break; + + case ADD: + os << "ADD"; + break; + + case SUB: + os << "SUB"; + break; + + case MULT: + os << "MULT"; + break; + + case DIV: + os << "DIV"; + break; + + case INVERT: + os << "INVERT"; + break; + + case COMPARE: + os << "COMPARE\t" << arg_; + break; + + case JUMP: + os << "JUMP\t" << arg_; + break; + + case JUMP_YES: + os << "JUMP_YES\t" << arg_; + break; + + case JUMP_NO: + os << "JUMP_NO\t" << arg_; + break; + + case INPUT: + os << "INPUT"; + break; + + case PRINT: + os << "PRINT"; + break; + } + + os << endl; +} + +void CodeGen::emit(Instruction instruction) +{ + commandBuffer_.push_back(Command(instruction)); +} + +void CodeGen::emit(Instruction instruction, int arg) +{ + commandBuffer_.push_back(Command(instruction, arg)); +} + +void CodeGen::emitAt(int address, Instruction instruction) +{ + commandBuffer_[address] = Command(instruction); +} + +void CodeGen::emitAt(int address, Instruction instruction, int arg) +{ + commandBuffer_[address] = Command(instruction, arg); +} + +int CodeGen::getCurrentAddress() +{ + return commandBuffer_.size(); +} + +int CodeGen::reserve() +{ + emit(NOP); + return commandBuffer_.size() - 1; +} + +void CodeGen::flush() +{ + int count = commandBuffer_.size(); + for(int address = 0; address < count; ++address) { + commandBuffer_[address].print(address, output_); + } + output_.flush(); +} diff --git a/lab4/cmilan/src/codegen.h b/lab4/cmilan/src/codegen.h new file mode 100644 index 0000000..9cba4c0 --- /dev/null +++ b/lab4/cmilan/src/codegen.h @@ -0,0 +1,100 @@ +#ifndef CMILAN_CODEGEN_H +#define CMILAN_CODEGEN_H + +#include +#include + +using namespace std; + +// Рнструкции виртуальной машины Милана + +enum Instruction +{ + NOP, // отсутствие операции + STOP, // остановка машины, завершение работы программы + LOAD, // LOAD addr - загрузка слова данных РІ стек РёР· памяти РїРѕ адресу addr + STORE, // STORE addr - запись слова данных СЃ вершины стека РІ память РїРѕ адресу addr + BLOAD, // BLOAD addr - загрузка слова данных РІ стек РёР· памяти РїРѕ адресу addr + значение РЅР° вершине стека + BSTORE, // BSTORE addr - запись слова данных РїРѕ адресу addr + значение РЅР° вершине стека + PUSH, // PUSH n - загрузка РІ стек константы n + POP, // удаление слова СЃ вершины стека + DUP, // копирование слова РЅР° вершине стека + ADD, // сложение РґРІСѓС… слов РЅР° вершине стека Рё запись результата вместо РЅРёС… + SUB, // вычитание РґРІСѓС… слов РЅР° вершине стека Рё запись результата вместо РЅРёС… + MULT, // умножение РґРІСѓС… слов РЅР° вершине стека Рё запись результата вместо РЅРёС… + DIV, // деление РґРІСѓС… слов РЅР° вершине стека Рё запись результата вместо РЅРёС… + INVERT, // изменение знака слова РЅР° вершине стека + COMPARE, // COMPARE cmp - сравнение РґРІСѓС… слов РЅР° вершине стека СЃ помощью операции сравнения СЃ РєРѕРґРѕРј cmp + JUMP, // JUMP addr - безусловный переход РїРѕ адресу addr + JUMP_YES, // JUMP_YES addr - переход РїРѕ адресу addr, если РЅР° вершине стека значение 1 + JUMP_NO, // JUMP_NO addr - переход РїРѕ адресу addr, если РЅР° вершине стека значение 0 + INPUT, // чтение целого числа СЃРѕ стандартного РІРІРѕРґР° Рё загрузка его РІ стек + PRINT // печать РЅР° стандартный вывод числа СЃ вершины стека +}; + +// Класс Command представляет машинные инструкции. + +class Command +{ +public: + // Конструктор для инструкций без аргументов + Command(Instruction instruction) + : instruction_(instruction), arg_(0) + {} + + // Конструктор для инструкций СЃ РѕРґРЅРёРј аргументом + Command(Instruction instruction, int arg) + : instruction_(instruction), arg_(arg) + {} + + // Печать инструкции + // int address - адрес инструкции + // ostream& os - поток вывода, РєСѓРґР° будет напечатана инструкция + void print(int address, ostream& os); + +private: + Instruction instruction_; // РљРѕРґ инструкции + int arg_; // Аргумент инструкции +}; + +// Кодогенератор. +// Назначение кодогенератора: +// - Формировать программу для виртуальной машины Милана +// - Отслеживать адрес последней инструкции +// - Буферизовать программу Рё печатать ее РІ указанный поток вывода + +class CodeGen +{ +public: + explicit CodeGen(ostream& output) + : output_(output) + { + } + + // Добавление инструкции без аргументов РІ конец программы + void emit(Instruction instruction); + + // Добавление инструкции СЃ РѕРґРЅРёРј аргументом РІ конец программы + void emit(Instruction instruction, int arg); + + // Запись инструкции без аргументов РїРѕ указанному адресу + void emitAt(int address, Instruction instruction); + + // Запись инструкции СЃ РѕРґРЅРёРј аргументом РїРѕ указанному адресу + void emitAt(int address, Instruction instruction, int arg); + + // Получение адреса, непосредственно следующего Р·Р° последней инструкцией РІ программе + int getCurrentAddress(); + + // Формирование "пустой" инструкции (NOP) Рё возврат ее адреса + int reserve(); + + // Запись последовательности инструкций РІ выходной поток + void flush(); + +private: + ostream& output_; // Выходной поток + vector commandBuffer_; // Буфер инструкций +}; + +#endif diff --git a/lab4/cmilan/src/codegen.o b/lab4/cmilan/src/codegen.o new file mode 100644 index 0000000000000000000000000000000000000000..06e9e6cf8578d00303761edc0dbaddfa73bb994d GIT binary patch literal 5991 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 U%=sZDHJ}a3imIm7@b) +#include + +using namespace std; + +void printHelp() +{ + cout << "Usage: cmilan input_file" << endl; +} + +int main(int argc, char** argv) +{ + if(argc < 2) { + printHelp(); + return EXIT_FAILURE; + } + + ifstream input; + input.open(argv[1]); + + if(input) { + Parser p(argv[1], input); + p.parse(); + return EXIT_SUCCESS; + } + else { + cerr << "File '" << argv[1] << "' not found" << endl; + return EXIT_FAILURE; + } +} + diff --git a/lab4/cmilan/src/main.o b/lab4/cmilan/src/main.o new file mode 100644 index 0000000000000000000000000000000000000000..66fbf99e8feaee05be9b6a05cb15ecb4cc55619d GIT binary patch literal 20476 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 + +//Выполняем синтаксический разбор блока program. Если РІРѕ время разбора РЅРµ обнаруживаем +//никаких ошибок, то выводим последовательность команд стек-машины +void Parser::parse() +{ + program(); + if(!error_) { + codegen_->flush(); + } +} + +void Parser::program() +{ + mustBe(T_BEGIN); + statementList(); + mustBe(T_END); + codegen_->emit(STOP); +} + +void Parser::statementList() +{ + // Если СЃРїРёСЃРѕРє операторов РїСѓСЃС‚, очередной лексемой будет РѕРґРЅР° РёР· возможных "закрывающих СЃРєРѕР±РѕРє": END, OD, ELSE, FI. + // Р’ этом случае результатом разбора будет пустой блок (его СЃРїРёСЃРѕРє операторов равен null). + // Если очередная лексема РЅРµ РІС…РѕРґРёС‚ РІ этот СЃРїРёСЃРѕРє, то ее РјС‹ считаем началом оператора Рё вызываем метод statement. + // Признаком последнего оператора является отсутствие после оператора точки СЃ запятой. + if(see(T_END) || see(T_OD) || see(T_ELSE) || see(T_FI)) { + return; + } + else { + bool more = true; + while(more) { + statement(); + more = match(T_SEMICOLON); + } + } +} + +void Parser::statement() +{ + // Если встречаем переменную, то запоминаем ее адрес или добавляем РЅРѕРІСѓСЋ если РЅРµ встретили. + // Следующей лексемой должно быть присваивание. Затем идет блок expression, который возвращает значение РЅР° вершину стека. + // Записываем это значение РїРѕ адресу нашей переменной + if(see(T_IDENTIFIER)) { + int varAddress = findOrAddVariable(scanner_->getStringValue()); + next(); + mustBe(T_ASSIGN); + expression(); + codegen_->emit(STORE, varAddress); + } + // Если встретили IF, то затем должно следовать условие. РќР° вершине стека лежит 1 или 0 РІ зависимости РѕС‚ выполнения условия. + // Затем зарезервируем место для условного перехода JUMP_NO Рє блоку ELSE (переход РІ случае ложного условия). Адрес перехода + // станет известным только после того, как будет сгенерирован РєРѕРґ для блока THEN. + else if(match(T_IF)) { + relation(); + + int jumpNoAddress = codegen_->reserve(); + + mustBe(T_THEN); + statementList(); + if(match(T_ELSE)) { + //Если есть блок ELSE, то чтобы РЅРµ выполнять его РІ случае выполнения THEN, + //зарезервируем место для команды JUMP РІ конец этого блока + int jumpAddress = codegen_->reserve(); + //Заполним зарезервированное место после проверки условия инструкцией перехода РІ начало блока ELSE. + codegen_->emitAt(jumpNoAddress, JUMP_NO, codegen_->getCurrentAddress()); + statementList(); + //Заполним второй адрес инструкцией перехода РІ конец условного блока ELSE. + codegen_->emitAt(jumpAddress, JUMP, codegen_->getCurrentAddress()); + } + else { + //Если блок ELSE отсутствует, то РІ зарезервированный адрес после проверки условия будет записана + //инструкция условного перехода РІ конец оператора IF...THEN + codegen_->emitAt(jumpNoAddress, JUMP_NO, codegen_->getCurrentAddress()); + } + + mustBe(T_FI); + } + + else if(match(T_WHILE)) { + //запоминаем адрес начала проверки условия. + int conditionAddress = codegen_->getCurrentAddress(); + relation(); + //резервируем место РїРѕРґ инструкцию условного перехода для выхода РёР· цикла. + int jumpNoAddress = codegen_->reserve(); + mustBe(T_DO); + statementList(); + mustBe(T_OD); + //переходим РїРѕ адресу проверки условия + codegen_->emit(JUMP, conditionAddress); + //заполняем зарезервированный адрес инструкцией условного перехода РЅР° следующий Р·Р° циклом оператор. + codegen_->emitAt(jumpNoAddress, JUMP_NO, codegen_->getCurrentAddress()); + } + else if(match(T_WRITE)) { + mustBe(T_LPAREN); + expression(); + mustBe(T_RPAREN); + codegen_->emit(PRINT); + } + else { + reportError("statement expected."); + } +} + +void Parser::expression() +{ + + /* + Арифметическое выражение описывается следующими правилами: -> | + | - + РџСЂРё разборе сначала смотрим первый терм, затем анализируем очередной СЃРёРјРІРѕР». Если это '+' или '-', + удаляем его РёР· потока Рё разбираем очередное слагаемое (вычитаемое). Повторяем проверку Рё разбор очередного + терма, РїРѕРєР° РЅРµ встретим Р·Р° термом СЃРёРјРІРѕР», отличный РѕС‚ '+' Рё '-' + */ + + term(); + while(see(T_ADDOP)) { + Arithmetic op = scanner_->getArithmeticValue(); + next(); + term(); + + if(op == A_PLUS) { + codegen_->emit(ADD); + } + else { + codegen_->emit(SUB); + } + } +} + +void Parser::term() +{ + /* + Терм описывается следующими правилами: -> | + | - + РџСЂРё разборе сначала смотрим первый множитель, затем анализируем очередной СЃРёРјРІРѕР». Если это '*' или '/', + удаляем его РёР· потока Рё разбираем очередное слагаемое (вычитаемое). Повторяем проверку Рё разбор очередного + множителя, РїРѕРєР° РЅРµ встретим Р·Р° РЅРёРј СЃРёРјРІРѕР», отличный РѕС‚ '*' Рё '/' + */ + factor(); + while(see(T_MULOP)) { + Arithmetic op = scanner_->getArithmeticValue(); + next(); + factor(); + + if(op == A_MULTIPLY) { + codegen_->emit(MULT); + } + else { + codegen_->emit(DIV); + } + } +} + +void Parser::factor() +{ + /* + Множитель описывается следующими правилами: + -> number | identifier | - | () | READ + */ + if(see(T_NUMBER)) { + int value = scanner_->getIntValue(); + next(); + codegen_->emit(PUSH, value); + //Если встретили число, то преобразуем его РІ целое Рё записываем РЅР° вершину стека + } + else if(see(T_IDENTIFIER)) { + int varAddress = findOrAddVariable(scanner_->getStringValue()); + next(); + codegen_->emit(LOAD, varAddress); + //Если встретили переменную, то выгружаем значение, лежащее РїРѕ ее адресу, РЅР° вершину стека + } + else if(see(T_ADDOP) && scanner_->getArithmeticValue() == A_MINUS) { + next(); + factor(); + codegen_->emit(INVERT); + //Если встретили знак "-", Рё Р·Р° РЅРёРј то инвертируем значение, лежащее РЅР° вершине стека + } + else if(match(T_LPAREN)) { + expression(); + mustBe(T_RPAREN); + //Если встретили открывающую СЃРєРѕР±РєСѓ, тогда следом может идти любое арифметическое выражение Рё обязательно + //закрывающая СЃРєРѕР±РєР°. + } + else if(match(T_READ)) { + codegen_->emit(INPUT); + //Если встретили зарезервированное слово READ, то записываем РЅР° вершину стека идет запись СЃРѕ стандартного РІРІРѕРґР° + } + else { + reportError("expression expected."); + } +} + +void Parser::relation() +{ + //Условие сравнивает РґРІР° выражения РїРѕ какому-либо РёР· знаков. Каждый знак имеет СЃРІРѕР№ номер. Р’ зависимости РѕС‚ + //результата сравнения РЅР° вершине стека окажется 0 или 1. + expression(); + if(see(T_CMP)) { + Cmp cmp = scanner_->getCmpValue(); + next(); + expression(); + switch(cmp) { + //для знака "=" - номер 0 + case C_EQ: + codegen_->emit(COMPARE, 0); + break; + //для знака "!=" - номер 1 + case C_NE: + codegen_->emit(COMPARE, 1); + break; + //для знака "<" - номер 2 + case C_LT: + codegen_->emit(COMPARE, 2); + break; + //для знака ">" - номер 3 + case C_GT: + codegen_->emit(COMPARE, 3); + break; + //для знака "<=" - номер 4 + case C_LE: + codegen_->emit(COMPARE, 4); + break; + //для знака ">=" - номер 5 + case C_GE: + codegen_->emit(COMPARE, 5); + break; + }; + } + else { + reportError("comparison operator expected."); + } +} + +int Parser::findOrAddVariable(const string& var) +{ + VarTable::iterator it = variables_.find(var); + if(it == variables_.end()) { + variables_[var] = lastVar_; + return lastVar_++; + } + else { + return it->second; + } +} + +void Parser::mustBe(Token t) +{ + if(!match(t)) { + error_ = true; + + // Подготовим сообщение РѕР± ошибке + std::ostringstream msg; + msg << tokenToString(scanner_->token()) << " found while " << tokenToString(t) << " expected."; + reportError(msg.str()); + + // Попытка восстановления после ошибки. + recover(t); + } +} + +void Parser::recover(Token t) +{ + while(!see(t) && !see(T_EOF)) { + next(); + } + + if(see(t)) { + next(); + } +} diff --git a/lab4/cmilan/src/parser.h b/lab4/cmilan/src/parser.h new file mode 100644 index 0000000..073ab7b --- /dev/null +++ b/lab4/cmilan/src/parser.h @@ -0,0 +1,119 @@ +#ifndef CMILAN_PARSER_H +#define CMILAN_PARSER_H + +#include "scanner.h" +#include "codegen.h" +#include +#include +#include +#include + +using namespace std; + +/* Синтаксический анализатор. + * + * Задачи: + * - проверка корректности программы, + * - генерация РєРѕРґР° для виртуальной машины РІ процессе анализа, + * - простейшее восстановление после ошибок. + * + * Синтаксический анализатор языка Милан. + * + * Парсер СЃ помощью переданного ему РїСЂРё инициализации лексического анализатора + * читает РїРѕ РѕРґРЅРѕР№ лексеме Рё РЅР° РѕСЃРЅРѕРІРµ грамматики Милана генерирует РєРѕРґ для + * стековой виртуальной машины. Синтаксический анализ выполняется методом + * рекурсивного СЃРїСѓСЃРєР°. + * + * РџСЂРё обнаружении ошибки парсер печатает сообщение Рё продолжает анализ СЃРѕ + * следующего оператора, чтобы РІ процессе разбора найти как РјРѕР¶РЅРѕ больше ошибок. + * Поскольку стратегия восстановления после ошибки очень проста, РІРѕР·РјРѕР¶РЅР° печать + * сообщений Рѕ несуществующих ("наведенных") ошибках или РїСЂРѕРїСѓСЃРє некоторых + * ошибок без печати сообщений. Если РІ процессе разбора была найдена хотя Р±С‹ + * РѕРґРЅР° ошибка, РєРѕРґ для виртуальной машины РЅРµ печатается.*/ + +class Parser +{ +public: + // Конструктор + // const string& fileName - РёРјСЏ файла СЃ программой для анализа + // + // Конструктор создает экземпляры лексического анализатора Рё генератора. + + Parser(const string& fileName, istream& input) + : output_(cout), error_(false), recovered_(true), lastVar_(0) + { + scanner_ = new Scanner(fileName, input); + codegen_ = new CodeGen(output_); + next(); + } + + ~Parser() + { + delete codegen_; + delete scanner_; + } + + void parse(); //РїСЂРѕРІРѕРґРёРј синтаксический разбор + +private: + typedef map VarTable; + //описание блоков. + void program(); //Разбор программы. BEGIN statementList END + void statementList(); // Разбор СЃРїРёСЃРєР° операторов. + void statement(); //разбор оператора. + void expression(); //разбор арифметического выражения. + void term(); //разбор слагаемого. + void factor(); //разбор множителя. + void relation(); //разбор условия. + + // Сравнение текущей лексемы СЃ образцом. Текущая позиция РІ потоке лексем РЅРµ изменяется. + bool see(Token t) + { + return scanner_->token() == t; + } + + // Проверка совпадения текущей лексемы СЃ образцом. Если лексема Рё образец совпадают, + // лексема изымается РёР· потока. + + bool match(Token t) + { + if(scanner_->token() == t) { + scanner_->nextToken(); + return true; + } + else { + return false; + } + } + + // Переход Рє следующей лексеме. + + void next() + { + scanner_->nextToken(); + } + + // Обработчик ошибок. + void reportError(const string& message) + { + cerr << "Line " << scanner_->getLineNumber() << ": " << message << endl; + error_ = true; + } + + void mustBe(Token t); //проверяем, совпадает ли данная лексема СЃ образцом. Если РґР°, то лексема изымается РёР· потока. + //Рначе создаем сообщение РѕР± ошибке Рё пробуем восстановиться + void recover(Token t); //восстановление после ошибки: идем РїРѕ РєРѕРґСѓ РґРѕ тех РїРѕСЂ, + //РїРѕРєР° РЅРµ встретим эту лексему или лексему конца файла. + int findOrAddVariable(const string&); //функция пробегает РїРѕ variables_. + //Если находит РЅСѓР¶РЅСѓСЋ переменную - возвращает ее номер, иначе добавляет ее РІ массив, увеличивает lastVar Рё возвращает его. + + Scanner* scanner_; //лексический анализатор для конструктора + CodeGen* codegen_; //указатель РЅР° виртуальную машину + ostream& output_; //выходной поток (РІ данном случае используем cout) + bool error_; //флаг ошибки. Рспользуется чтобы определить, выводим ли СЃРїРёСЃРѕРє команд после разбора или нет + bool recovered_; //РЅРµ используется + VarTable variables_; //массив переменных, найденных РІ программе + int lastVar_; //номер последней записанной переменной +}; + +#endif diff --git a/lab4/cmilan/src/parser.o b/lab4/cmilan/src/parser.o new file mode 100644 index 0000000000000000000000000000000000000000..9ed6d500f842a20f86ce724f690942688f23f9a8 GIT binary patch literal 18027 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 literal 0 HcmV?d00001 diff --git a/lab4/cmilan/src/scanner.cpp b/lab4/cmilan/src/scanner.cpp new file mode 100644 index 0000000..29f5474 --- /dev/null +++ b/lab4/cmilan/src/scanner.cpp @@ -0,0 +1,233 @@ +#include "scanner.h" +#include +#include +#include + +using namespace std; + +static const char * tokenNames_[] = { + "end of file", + "illegal token", + "identifier", + "number", + "'BEGIN'", + "'END'", + "'IF'", + "'THEN'", + "'ELSE'", + "'FI'", + "'WHILE'", + "'DO'", + "'OD'", + "'WRITE'", + "'READ'", + "':='", + "'+' or '-'", + "'*' or '/'", + "comparison operator", + "'('", + "')'", + "';'", +}; + +void Scanner::nextToken() +{ + skipSpace(); + + // Пропускаем комментарии + // Если встречаем "/", то Р·Р° РЅРёРј должна идти "*". Если "*" РЅРµ встречена, считаем, что встретили операцию деления + // Рё лексему - операция типа умножения. Дальше смотрим РІСЃРµ символы, РїРѕРєР° РЅРµ находим звездочку или СЃРёРјРІРѕР» конца файла. + // Если нашли * - проверяем РЅР° наличие "/" после нее. Если "/" РЅРµ найден - ищем следующую "*". + while(ch_ == '/') { + nextChar(); + if(ch_ == '*') { + nextChar(); + bool inside = true; + while(inside) { + while(ch_ != '*' && !input_.eof()) { + nextChar(); + } + + if(input_.eof()) { + token_ = T_EOF; + return; + } + + nextChar(); + if(ch_ == '/') { + inside = false; + nextChar(); + } + } + } + else { + token_ = T_MULOP; + arithmeticValue_ = A_DIVIDE; + return; + } + + skipSpace(); + } + + //Если встречен конец файла, считаем Р·Р° лексему конца файла. + if(input_.eof()) { + token_ = T_EOF; + return; + } + //Если встретили цифру, то РґРѕ тех РїРѕРєР° дальше РёРґСѓС‚ цифры - считаем как продолжение числа. + //Запоминаем полученное целое, Р° Р·Р° лексему считаем целочисленный литерал + + if(isdigit(ch_)) { + int value = 0; + while(isdigit(ch_)) { + value = value * 10 + (ch_ - '0'); //поразрядное считывание, преобразуем символьное значение Рє числу. + nextChar(); + } + token_ = T_NUMBER; + intValue_ = value; + } + //Если Р¶Рµ следующий СЃРёРјРІРѕР» - Р±СѓРєРІР° ЛА - тогда считываем РґРѕ тех РїРѕСЂ, РїРѕРєР° дальше Р±СѓРєРІС‹ ЛА или цифры. + //Как только считали РёРјСЏ переменной, сравниваем ее СЃРѕ СЃРїРёСЃРєРѕРј зарезервированных слов. Если РЅРµ совпадает РЅРё СЃ РѕРґРЅРёРј РёР· РЅРёС…, + //считаем, что получили переменную, РёРјСЏ которой запоминаем, Р° Р·Р° текущую лексему считаем лексему идентификатора. + //Если совпадает СЃ каким-либо словом РёР· СЃРїРёСЃРєР° - считаем что получили лексему, соответствующую этому слову. + else if(isIdentifierStart(ch_)) { + string buffer; + while(isIdentifierBody(ch_)) { + buffer += ch_; + nextChar(); + } + + transform(buffer.begin(), buffer.end(), buffer.begin(), ::tolower); + + map::iterator kwd = keywords_.find(buffer); + if(kwd == keywords_.end()) { + token_ = T_IDENTIFIER; + stringValue_ = buffer; + } + else { + token_ = kwd->second; + } + } + //РЎРёРјРІРѕР» РЅРµ является Р±СѓРєРІРѕР№, цифрой, "/" или признаком конца файла + else { + switch(ch_) { + //Признак лексемы открывающей СЃРєРѕР±РєРё - встретили "(" + case '(': + token_ = T_LPAREN; + nextChar(); + break; + //Признак лексемы закрывающей СЃРєРѕР±РєРё - встретили ")" + case ')': + token_ = T_RPAREN; + nextChar(); + break; + //Признак лексемы ";" - встретили ";" + case ';': + token_ = T_SEMICOLON; + nextChar(); + break; + //Если встречаем ":", то дальше смотрим наличие символа "=". Если находим, то считаем что нашли лексему присваивания + //Рначе - лексема ошибки. + case ':': + nextChar(); + if(ch_ == '=') { + token_ = T_ASSIGN; + nextChar(); + + } + else { + token_ = T_ILLEGAL; + } + break; + //Если встретили СЃРёРјРІРѕР» "<", то либо следующий СЃРёРјРІРѕР» "=", тогда лексема нестрогого сравнения. Рначе - строгого. + case '<': + token_ = T_CMP; + nextChar(); + if(ch_ == '=') { + cmpValue_ = C_LE; + nextChar(); + } + else { + cmpValue_ = C_LT; + } + break; + //Аналогично предыдущему случаю + case '>': + token_ = T_CMP; + nextChar(); + if(ch_ == '=') { + cmpValue_ = C_GE; + nextChar(); + } + else { + cmpValue_ = C_GT; + } + break; + //Если встретим "!", то дальше должно быть "=", тогда считаем, что получили лексему сравнения + //Рё знак "!=" иначе считаем, что Сѓ нас лексема ошибки + case '!': + nextChar(); + if(ch_ == '=') { + nextChar(); + token_ = T_CMP; + cmpValue_ = C_NE; + } + else { + token_ = T_ILLEGAL; + } + break; + //Если встретим "=" - лексема сравнения Рё знак "=" + case '=': + token_ = T_CMP; + cmpValue_ = C_EQ; + nextChar(); + break; + //Знаки операций. Для "+"/"-" получим лексему операции типа сложнения, Рё соответствующую операцию. + //для "*" - лексему операции типа умножения + case '+': + token_ = T_ADDOP; + arithmeticValue_ = A_PLUS; + nextChar(); + break; + + case '-': + token_ = T_ADDOP; + arithmeticValue_ = A_MINUS; + nextChar(); + break; + + case '*': + token_ = T_MULOP; + arithmeticValue_ = A_MULTIPLY; + nextChar(); + break; + //Рначе лексема ошибки. + default: + token_ = T_ILLEGAL; + nextChar(); + break; + } + } +} + +void Scanner::skipSpace() +{ + while(isspace(ch_)) { + if(ch_ == '\n') { + ++lineNumber_; + } + + nextChar(); + } +} + +void Scanner::nextChar() +{ + ch_ = input_.get(); +} + +const char * tokenToString(Token t) +{ + return tokenNames_[t]; +} + diff --git a/lab4/cmilan/src/scanner.h b/lab4/cmilan/src/scanner.h new file mode 100644 index 0000000..15d1523 --- /dev/null +++ b/lab4/cmilan/src/scanner.h @@ -0,0 +1,164 @@ +#ifndef CMILAN_SCANNER_H +#define CMILAN_SCANNER_H + +#include +#include +#include + +using namespace std; + +enum Token { + T_EOF, // Конец текстового потока + T_ILLEGAL, // Признак недопустимого символа + T_IDENTIFIER, // Рдентификатор + T_NUMBER, // Целочисленный литерал + T_BEGIN, // Ключевое слово "begin" + T_END, // Ключевое слово "end" + T_IF, // Ключевое слово "if" + T_THEN, // Ключевое слово "then" + T_ELSE, // Ключевое слово "else" + T_FI, // Ключевое слово "fi" + T_WHILE, // Ключевое слово "while" + T_DO, // Ключевое слово "do" + T_OD, // Ключевое слово "od" + T_WRITE, // Ключевое слово "write" + T_READ, // Ключевое слово "read" + T_ASSIGN, // Оператор ":=" + T_ADDOP, // Сводная лексема для "+" Рё "-" (операция типа сложения) + T_MULOP, // Сводная лексема для "*" Рё "/" (операция типа умножения) + T_CMP, // Сводная лексема для операторов отношения + T_LPAREN, // Открывающая СЃРєРѕР±РєР° + T_RPAREN, // Закрывающая СЃРєРѕР±РєР° + T_SEMICOLON // ";" +}; + +// Функция tokenToString возвращает описание лексемы. +// Рспользуется РїСЂРё печати сообщения РѕР± ошибке. +const char * tokenToString(Token t); + +// Р’РёРґС‹ операций сравнения +enum Cmp { + C_EQ, // Операция сравнения "=" + C_NE, // Операция сравнения "!=" + C_LT, // Операция сравнения "<" + C_LE, // Операция сравнения "<=" + C_GT, // Операция сравнения ">" + C_GE // Операция сравнения ">=" +}; + +// Р’РёРґС‹ арифметических операций +enum Arithmetic { + A_PLUS, //операция "+" + A_MINUS, //операция "-" + A_MULTIPLY, //операция "*" + A_DIVIDE //операция "/" +}; + +// Лексический анализатор + +class Scanner +{ +public: + // Конструктор. Р’ качестве аргумента принимает РёРјСЏ файла Рё поток, + // РёР· которого Р±СѓРґСѓС‚ читаться символы транслируемой программы. + + explicit Scanner(const string& fileName, istream& input) + : fileName_(fileName), lineNumber_(1), input_(input) + { + keywords_["begin"] = T_BEGIN; + keywords_["end"] = T_END; + keywords_["if"] = T_IF; + keywords_["then"] = T_THEN; + keywords_["else"] = T_ELSE; + keywords_["fi"] = T_FI; + keywords_["while"] = T_WHILE; + keywords_["do"] = T_DO; + keywords_["od"] = T_OD; + keywords_["write"] = T_WRITE; + keywords_["read"] = T_READ; + + nextChar(); + } + + // Деструктор + virtual ~Scanner() + {} + + //getters всех private переменных + const string& getFileName() const //РЅРµ используется + { + return fileName_; + } + + int getLineNumber() const + { + return lineNumber_; + } + + Token token() const + { + return token_; + } + + int getIntValue() const + { + return intValue_; + } + + string getStringValue() const + { + return stringValue_; + } + + Cmp getCmpValue() const + { + return cmpValue_; + } + + Arithmetic getArithmeticValue() const + { + return arithmeticValue_; + } + + // Переход Рє следующей лексеме. + // Текущая лексема записывается РІ token_ Рё изымается РёР· потока. + void nextToken(); +private: + + // РџСЂРѕРїСѓСЃРє всех пробельные символы. + // Если встречается СЃРёРјРІРѕР» перевода строки, номер текущей строки + // (lineNumber) увеличивается РЅР° единицу. + void skipSpace(); + + + void nextChar(); //переходит Рє следующему символу + //проверка переменной РЅР° первый СЃРёРјРІРѕР» (должен быть Р±СѓРєРІРѕР№ латинского алфавита) + bool isIdentifierStart(char c) + { + return ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z')); + } + //проверка РЅР° остальные символы переменной (Р±СѓРєРІР° или цифра) + bool isIdentifierBody(char c) + { + return isIdentifierStart(c) || isdigit(c); + } + + + const string fileName_; //РІС…РѕРґРЅРѕР№ файл + int lineNumber_; //номер текущей строки РєРѕРґР° + + Token token_; //текущая лексема + int intValue_; //значение текущего целого + string stringValue_; //РёРјСЏ переменной + Cmp cmpValue_; //значение оператора сравнения (>, <, =, !=, >=, <=) + Arithmetic arithmeticValue_; //значение знака (+,-,*,/) + + map keywords_; //ассоциативный массив СЃ лексемами Рё + //соответствующими РёРј зарезервированными словами РІ качестве индексов + + istream& input_; //РІС…РѕРґРЅРѕР№ поток для чтения РёР· файла. + char ch_; //текущий СЃРёРјРІРѕР» +}; + +#endif diff --git a/lab4/cmilan/src/scanner.o b/lab4/cmilan/src/scanner.o new file mode 100644 index 0000000000000000000000000000000000000000..f5783ebfc996650e3d3e89278325df9469bc546e GIT binary patch literal 6500 zcmeHLeQaCR6~9j0H2t72g>7mX(8n-KTJmAHCXJ!p>?AJFsvEpGkPZqjuI)5l9mlm_ z(xhT*rX8!F*vKuaUsKDUcD;cZjAu=1RrpxV|ke`NK zvuU^1v}0DpP!lZ-R--}*L4>UBc$YRCI8Zir+64IE!-?^ z8YPi;v`B%pQ6RY`p7mL;H1(cdD87nVUN!aT&?HT~iLN|kBZeJYq={x4{&F8D&G~+` zW$@aC02<>oYBMnb#-JW^ID`6GC7*OS zmDzSj3xup)pD%SC>i0=g&zgfq6x;b=u7OMx&w1@?X=M4^Lq8RdL4TngnZ51D>c2!SgsM4OTA#B!m)Ryt?g2-OPk&a)X%1(h1sNE7??x=h_0mH> zqJ5SBECueBP85}>{b|KES3Ki)z2J9EEBZ%@UZB~_u;bgxaI)~wlXS!j!#u%sUtxAF zm?V$5fy=Khb>cf>$4>3&Y};Nt^&J0CvFLgQi$gYgc&}wO3w_X;8jBdcZ$fVxtFVh( zP}~-aLX#ohOABq?l6>^SdalJYV>#{n9~X-jUpsb6<9~rA;-IM)PD2e`V~F;NY?!W3 zaP4QHwfHD}pNp?qB0jcssKH0A;hIzDt}$a{{4VZl>A*W7c1@ds>23S0qu?-y|)lX?jc9n{bJeuL&{;J4U#M?uAfwbCZ2hc>`g zYgKah*X_|S1U(mn(yp036VqCalIxI5`xQ5^6x@6<==s~%*91Ka-`K`b=DS)F#uLhu?9+2Dh3lq};Nx7ux7jWU$ zEnc`jbp~-F{)M+Ek>{FKtfqCXb4}0c^r}$xbk&^wOvO3)K=}t}c+By^6#dV}py*as zW^ufVpi1O$C1?#u0$l_89pq1eI)QHk)q;+r-2}c3v>kLi=*yrs&>f)NpgTcfP&epa z&@}oS0);`hgRTd~Q!#mHF)PY^7x)i@535NY>?FyjkRsun4wBL#9PO|Lo40MsC)9<6^Z97rjQY#N+ z;zP@p?4B0baPi4&#RKg5Hsul31cm6=MXTR-SYCZ=?70fGv@Mnk@btFjS`c<_WjEwHcFmRN;_dgnWR77AMF<#mu%E~V#(0Z$dX=; zvR&_Px=0TUs zP;^B4<5{d1MRdjF=Stbd)@)N&`DrN2w#OoGj1DAY|KIxm`(pU?TVGA|r`1F@OIx0) zMoSw=4jjfusHz?q9#-*jh>yfbGNFyA__T4-sR$>w9f)iEgnaVL(4+2A`vg zgmy 1 DO + t := a; + a := b; + b := b + t; + n := n - 1 + OD; + + WRITE(a) +END + diff --git a/lab4/cmilan/test/gcd.mil b/lab4/cmilan/test/gcd.mil new file mode 100644 index 0000000..b669e9a --- /dev/null +++ b/lab4/cmilan/test/gcd.mil @@ -0,0 +1,17 @@ +/* Greatest common divisor */ + +BEGIN + a := READ; + b := READ; + + WHILE a != b DO + IF a < b THEN + b := b - a + ELSE + a := a - b + FI + OD; + + WRITE(a) +END + diff --git a/lab4/cmilan/test/if.mil b/lab4/cmilan/test/if.mil new file mode 100644 index 0000000..e81aa1d --- /dev/null +++ b/lab4/cmilan/test/if.mil @@ -0,0 +1,8 @@ +BEGIN + i := 1; + j := 2; + + IF i < j THEN WRITE(i) FI; + IF i < j THEN WRITE(i) ELSE WRITE(j) FI +END + diff --git a/lab4/cmilan/test/invalid.mil b/lab4/cmilan/test/invalid.mil new file mode 100644 index 0000000..a8db7e7 --- /dev/null +++ b/lab4/cmilan/test/invalid.mil @@ -0,0 +1,5 @@ +BEGIN + IF 1 2 THEN WRITE(n) ELSE WRITE(2) FI; + X := Y + 1; + WRITE (X +) +END diff --git a/lab4/cmilan/test/invert.mil b/lab4/cmilan/test/invert.mil new file mode 100644 index 0000000..21321a5 --- /dev/null +++ b/lab4/cmilan/test/invert.mil @@ -0,0 +1,14 @@ +BEGIN + x := READ; + x := -x; + + WRITE(-x); + + IF -x > 0 THEN x := 1 FI; + + x := x + -1; + x := x - -x; + + x := x -1 +END + diff --git a/lab4/cmilan/test/loop.mil b/lab4/cmilan/test/loop.mil new file mode 100644 index 0000000..b57e777 --- /dev/null +++ b/lab4/cmilan/test/loop.mil @@ -0,0 +1,17 @@ +BEGIN + /* Read a number */ + + i := READ; + + /* Count from 0 to this number */ + + IF i > 0 THEN step := 1 ELSE step := -1 FI; + k := 0; + WHILE k != i DO + WRITE(k); + k := k + step + OD; + + WRITE(i) +END + diff --git a/lab4/cmilan/test/power.mil b/lab4/cmilan/test/power.mil new file mode 100644 index 0000000..7661a84 --- /dev/null +++ b/lab4/cmilan/test/power.mil @@ -0,0 +1,14 @@ +BEGIN + N := READ; + P := READ; + + S := 1; + + WHILE P > 0 DO + S := S * N; + P := P - 1 + OD; + + WRITE(S) +END + diff --git a/lab4/cmilan/test/read2.mil b/lab4/cmilan/test/read2.mil new file mode 100644 index 0000000..3b4ed25 --- /dev/null +++ b/lab4/cmilan/test/read2.mil @@ -0,0 +1,8 @@ +BEGIN + IF READ < READ + THEN + WRITE(1) + ELSE + WRITE(2) + FI +END diff --git a/lab4/cmilan/test/sum.mil b/lab4/cmilan/test/sum.mil new file mode 100644 index 0000000..507ca7c --- /dev/null +++ b/lab4/cmilan/test/sum.mil @@ -0,0 +1,9 @@ +BEGIN + i := 8; + j := 2; + + WHILE i != j DO + IF i < j THEN j := j - i ELSE i := i - j FI + OD; + WRITE(i) +END diff --git a/lab4/vm/bin/milanvm.exe b/lab4/vm/bin/milanvm.exe new file mode 100644 index 0000000000000000000000000000000000000000..0add2db9681ff7e8857cffbac3b4e339494d4aa2 GIT binary patch literal 82432 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
    @E|8;aP$ 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 + + Помещает в стек слово, расположенное в памяти по адресу <адрес>. + +STORE <адрес> + + Выталкивает из стека слово и записывает его в память по адресу <адрес>. + Если нужная ячейка находится за пределами рабочей области памяти, диагностируется + ошибка времени исполнения. + + +BLOAD <адрес> + + Помещает в стек слово, адрес которого вычисляется следующим образом: + <адрес в памяти> = <адрес> + <значение с вершины стека>. Значение + с вершины стека удаляется. + + Команду BLOAD можно использовать, например, для обращения к элементу массива + или к переменной, адрес которой вычисляется во время выполнения + программы. + +BSTORE <адрес> + + Вычисляет адрес в памяти по формуле: + <адрес в памяти> = <адрес> + <значение с вершины стека>, значение + с вершины стека при этом удаляется. Выталкивает из стека слово и записывает + его по адресу <адрес в памяти>. + + Команду BSTORE можно использовать для записи значения в элемент + массива или в переменную, адрес которой вычисляется во время выполнения + программы. + + Пусть стек имеет вид: [10, 20, ...]. В этом случае команда BSTORE 5 + запишет по адресу 15 число 20. + +PUSH <значение> + + Заталкивает <значение> в стек. + +POP + + Выталкивает слово из стека. + +DUP + + Заталкивает в стек значение, равное значению на вершине стека. + +ADD + + Выталкивает из стека два числа и заталкивает в стек результат их + сложения. + +MULT + + Выталкивает из стека два числа и заталкивает в стек результат их + умножения. + +SUB + + Выталкивает из стека число , выталкивает из стека число + и заталкивает в стек разность - . + + Пример: после выполнения последовательности команд + + PUSH 10 + PUSH 8 + SUB + + на вершине стека будет находиться число 2. + +DIV + + Выталкивает из стека число , выталкивает из стека число + и заталкивает в стек частное / . Используется целочисленное + деление. Если значение = 0, то диагностируется ошибка времени + исполнения. + +INVERT + + Меняет знак числа на вершине стека на противоположный. + +COMPARE <код> + + Выталкивает из стека число , выталкивает из стека число , + затем заталкивает в стек результат сравнения и . + + Операция сравнения определяется значением аргумента <код>: + + <код> операция + + 0 = + 1 != + 2 < + 3 > + 4 <= + 5 >= + + Результатом сравнения является значение 1, если требуемое неравенство + выполняется, и 0 в противном случае. + + Пример: после выполнения последовательности команд + + PUSH 5 + PUSH 7 + COMPARE 2 + + на вершине стека будет находиться значение 1 (так как 5 < 7). + +JUMP <адрес> + + Выполняет переход по адресу <адрес>, то есть устанавливает адрес + следующей исполняемой команды равным <адрес>. Если + <адрес> меньше нуля или больше, чем адрес последней команды + в программе, диагностируется ошибка времени исполнения. + + +JUMP_YES <адрес> + + Выполняет переход по адресу <адрес>, если на вершине стека + находится ненулевое значение; слово выталкивается из стека. + +JUMP_NO <адрес> + + Выполняет переход по адресу <адрес>, если на вершине стека + находится значение 0; слово выталкивается из стека. Если + <адрес> меньше нуля или больше, чем адрес последней команды + в программе, диагностируется ошибка времени исполнения. + +INPUT + + Считывает целочисленное значение со стандартного устройства ввода + и заталкивает его в стек. В случае ошибки ввода-вывода или + несоответсвия формата диагностируется ошибка времени исполнения. + +PRINT + + Выталкивает из стека слово и выводит его на стандартное устройство + ввода. Значение форматируется как целое число. + +Каждая команда исполняется за один такт работы виртуальной машины. + +Виртуальная машина формирует содержимое памяти команд и данных, читая и интерпретируя +текстовый файл программы. Файл имеет следующий формат. + +Файл читается как последовательность строк. Символ ';' начинает комментарий, все +символы, начиная с него и до конца строки, игнорируются. + +Команда состоит из адреса, кода операции и аргумента, если он требуется. +Адрес является целым числом, за которым следует символ ':'. Нумерация команд +начинается с 0. + +Код операции совпадает с описанным ранее символьным обозначением, +например: STOP. Если команда имеет аргумент, он должен быть целым числом. + +Пример корректной программы на языке виртуальной машины Милана: + +------------------------------------------------------------ +0: INPUT +1: STORE 42 ; n := READ +2: LOAD 14 +3: PUSH 4 +4: LOAD 42 +5: COMPARE 2 +6: JUMP_NO 9 +7: PUSH 10 +8: STORE 42 +9: LOAD 42 +10: PRINT +11: STOP +------------------------------------------------------------- + +Для инициализации памяти данных используется служебная инструкция виртуальной +машины SET: + + SET <адрес> <значение> + +В результате исполнения инструкции SET по адресу <адрес> в память данных +записывается слово <значение>. + +Инструкция SET не сохраняется в памяти команд. Она служит для инициализации +памяти перед началом исполнения программы. Компилятор может генерировать +блок команд SET для задания значений констант и статически инициализированных +переменных. + +Инструкция SET <адрес> <значение> эквивалентна паре команд + + PUSH <значение> + STORE <адрес> + +и выполняется за один такт. + +Инструкция SET не требует указания адреса. Пример корректного использованя SET: + +------------------------------------ +SET 0 15 +SET 1 40 + +0: LOAD 0 +1: LOAD 1 +2: ADD +3: PRINT +4: STOP +------------------------------------ + +В результате выполнения этой программы будет напечатано число 55. + diff --git a/lab4/vm/vm/Makefile b/lab4/vm/vm/Makefile new file mode 100644 index 0000000..53415a7 --- /dev/null +++ b/lab4/vm/vm/Makefile @@ -0,0 +1,15 @@ +mvm: vm.c lex.yy.c vmparse.tab.h main.c + gcc -o mvm main.c vm.c lex.yy.c vmparse.tab.c + +lex.yy.c: vmlex.l + flex vmlex.l + +vmparse.tab.h: vmparse.y + bison -d vmparse.y + +clean: + rm lex.yy.c vmparse.tab.h vmparse.tab.c + +distclean: + rm mvm lex.yy.c vmparse.tab.h vmparse.tab.c + diff --git a/lab4/vm/vm/lex.yy.c b/lab4/vm/vm/lex.yy.c new file mode 100644 index 0000000..ddc430f --- /dev/null +++ b/lab4/vm/vm/lex.yy.c @@ -0,0 +1,1690 @@ +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define yywrap() 1 +#define YY_SKIP_YYWRAP +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 27 +#define YY_END_OF_BUFFER 28 +static yyconst short int yy_accept[91] = + { 0, + 0, 0, 28, 27, 3, 1, 27, 4, 5, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 3, 4, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, 19, 14, 0, 0, + 0, 0, 0, 26, 13, 0, 0, 6, 0, 17, + 0, 0, 0, 0, 0, 21, 8, 18, 0, 12, + 7, 0, 10, 0, 0, 24, 0, 0, 25, 9, + 11, 0, 15, 0, 0, 20, 23, 0, 22, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 4, 1, 1, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 6, 7, 1, + 1, 1, 1, 1, 8, 9, 10, 11, 12, 1, + 1, 13, 14, 15, 1, 16, 17, 18, 19, 20, + 1, 21, 22, 23, 24, 25, 1, 1, 26, 1, + 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[28] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1 + } ; + +static yyconst short int yy_base[92] = + { 0, + 0, 0, 100, 101, 97, 101, 93, 92, 101, 93, + 84, 12, 75, 15, 75, 68, 72, 66, 70, 11, + 19, 86, 82, 83, 101, 74, 65, 60, 65, 56, + 60, 13, 62, 70, 61, 56, 55, 60, 51, 49, + 52, 61, 101, 61, 49, 47, 101, 101, 42, 53, + 44, 52, 39, 101, 101, 43, 47, 101, 16, 101, + 48, 37, 49, 33, 34, 27, 101, 101, 30, 101, + 101, 40, 101, 39, 29, 101, 26, 22, 101, 101, + 101, 35, 101, 27, 33, 101, 101, 22, 101, 101, + 40 + + } ; + +static yyconst short int yy_def[92] = + { 0, + 90, 1, 90, 90, 90, 90, 90, 90, 90, 91, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 91, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 0, + 90 + + } ; + +static yyconst short int yy_nxt[129] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 4, 4, 15, 16, 17, 18, 19, 4, 20, + 4, 21, 4, 4, 4, 4, 4, 27, 30, 37, + 40, 38, 49, 28, 39, 71, 72, 50, 31, 84, + 24, 41, 42, 89, 88, 87, 86, 85, 83, 82, + 81, 80, 79, 78, 77, 76, 75, 74, 73, 70, + 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, + 59, 58, 57, 56, 55, 54, 53, 52, 51, 48, + 47, 46, 45, 44, 43, 25, 23, 22, 36, 35, + 34, 33, 32, 29, 26, 25, 23, 23, 22, 90, + + 3, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90 + } ; + +static yyconst short int yy_chk[129] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 12, 14, 20, + 21, 20, 32, 12, 20, 59, 59, 32, 14, 78, + 91, 21, 21, 88, 85, 84, 82, 78, 77, 75, + 74, 72, 69, 66, 65, 64, 63, 62, 61, 57, + 56, 53, 52, 51, 50, 49, 46, 45, 44, 42, + 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, + 30, 29, 28, 27, 26, 24, 23, 22, 19, 18, + 17, 16, 15, 13, 11, 10, 8, 7, 5, 3, + + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "vmlex.l" +#define INITIAL 0 +#line 2 "vmlex.l" +#include "vmparse.tab.h" +#include + +#ifndef __GNUC__ +#define YY_NO_UNISTD_H +#endif +#line 429 "lex.yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 17 "vmlex.l" + + +#line 583 "lex.yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 91 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 101 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 19 "vmlex.l" + + YY_BREAK +case 2: +YY_RULE_SETUP +#line 20 "vmlex.l" + + YY_BREAK +case 3: +YY_RULE_SETUP +#line 21 "vmlex.l" + + YY_BREAK +case 4: +YY_RULE_SETUP +#line 22 "vmlex.l" +{ yylval = atoi(yytext); return T_INT; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 24 "vmlex.l" +{ return T_COLON; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 26 "vmlex.l" +{ return T_SET; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 27 "vmlex.l" +{ return T_STOP; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 28 "vmlex.l" +{ return T_LOAD; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 29 "vmlex.l" +{ return T_STORE; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 30 "vmlex.l" +{ return T_BLOAD; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 31 "vmlex.l" +{ return T_BSTORE; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 32 "vmlex.l" +{ return T_PUSH; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 33 "vmlex.l" +{ return T_POP; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 34 "vmlex.l" +{ return T_DUP; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 35 "vmlex.l" +{ return T_INVERT; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 36 "vmlex.l" +{ return T_ADD; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 37 "vmlex.l" +{ return T_SUB; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 38 "vmlex.l" +{ return T_MULT; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 39 "vmlex.l" +{ return T_DIV; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 40 "vmlex.l" +{ return T_COMPARE; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 41 "vmlex.l" +{ return T_JUMP; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 42 "vmlex.l" +{ return T_JUMP_YES; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 43 "vmlex.l" +{ return T_JUMP_NO; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 44 "vmlex.l" +{ return T_INPUT; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 45 "vmlex.l" +{ return T_PRINT; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 46 "vmlex.l" +{ return T_NOP; } + YY_BREAK +case YY_STATE_EOF(INITIAL): +#line 48 "vmlex.l" +{ yyterminate(); } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 50 "vmlex.l" +ECHO; + YY_BREAK +#line 805 "lex.yy.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 91 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 91 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 90); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 50 "vmlex.l" + + diff --git a/lab4/vm/vm/main.c b/lab4/vm/vm/main.c new file mode 100644 index 0000000..31698c7 --- /dev/null +++ b/lab4/vm/vm/main.c @@ -0,0 +1,46 @@ +#include "vm.h" +#include "vmparse.tab.h" +#include +#include + +extern FILE *yyin; +int need_close = 0; + +int yyparse(); + +void milan_error(char const * msg) +{ + if(need_close) + fclose(yyin); + + fprintf(stderr, msg); + exit(1); +} + +int main(int argc, char **argv) +{ + if(argc < 2) { + yyin = stdin; + printf("Reading input from stdin\n"); + } + else { + yyin = fopen(argv[1], "rt"); + if(!yyin) { + printf("Unable to read %s\n", argv[1]); + return 1; + } + + need_close = 1; + printf("Reading input from %s\n", argv[1]); + } + + if(0 == yyparse()) { + run(); + } + + if(need_close) { + fclose(yyin); + } + + return 0; +} diff --git a/lab4/vm/vm/test/bop1.ms b/lab4/vm/vm/test/bop1.ms new file mode 100644 index 0000000..296b955 --- /dev/null +++ b/lab4/vm/vm/test/bop1.ms @@ -0,0 +1,6 @@ +4: STOP +1: PUSH 20 +2: ADD +3: PRINT +0: PUSH 10 +2: MULT diff --git a/lab4/vm/vm/test/bop2.ms b/lab4/vm/vm/test/bop2.ms new file mode 100644 index 0000000..0ae0d54 --- /dev/null +++ b/lab4/vm/vm/test/bop2.ms @@ -0,0 +1,8 @@ +0: PUSH 10 +1: PUSH -1 +2: BSTORE 2 +3: PUSH 0 +4: BLOAD 1 +5: PRINT +6: STOP + diff --git a/lab4/vm/vm/test/fib.ms b/lab4/vm/vm/test/fib.ms new file mode 100644 index 0000000..654666a --- /dev/null +++ b/lab4/vm/vm/test/fib.ms @@ -0,0 +1,37 @@ +; Вычисление N-го числа Фибоначчи + +SET 0 0 ; Константа 0 +SET 1 1 ; Константа 1 + +SET 1000 0 ; Переменная n +SET 1001 1 ; Переменная a +SET 1002 1 ; Переменная b + +; Программа + + 0: INPUT + 1: STORE 1000 ; n := READ + + 2: LOAD 1000 + 3: LOAD 1 + 4: COMPARE 3 ; IF n > 1 + 5: JUMP_NO 17 + + 6: LOAD 1002 ; STACK <- b + 7: LOAD 1001 ; STACK <- a + 8: LOAD 1002 + 9: STORE 1001 ; a := b +10: ADD +11: STORE 1002 ; b := старое_значение_a + b + +12: LOAD 1000 +13: LOAD 1 +14: SUB +15: STORE 1000 ; n := n - 1 +16: JUMP 2 + +17: LOAD 1001 ; WRITE(a) +18: PRINT + +19: STOP + diff --git a/lab4/vm/vm/test/fib2.ms b/lab4/vm/vm/test/fib2.ms new file mode 100644 index 0000000..fd01c89 --- /dev/null +++ b/lab4/vm/vm/test/fib2.ms @@ -0,0 +1,21 @@ +SET 0 1 +SET 1 1 + + 0: INPUT + 1: DUP + 2: PUSH 1 + 3: COMPARE 3 + 4: JUMP_NO 14 + 5: LOAD 1 + 6: LOAD 0 + 7: LOAD 1 + 8: STORE 0 + 9: ADD +10: STORE 1 +11: PUSH 1 +12: SUB +13: JUMP 1 +14: LOAD 0 +15: PRINT +16: STOP + \ No newline at end of file diff --git a/lab4/vm/vm/vm.c b/lab4/vm/vm/vm.c new file mode 100644 index 0000000..5738940 --- /dev/null +++ b/lab4/vm/vm/vm.c @@ -0,0 +1,371 @@ +#include +#include +#include "vm.h" + +void milan_error(); + +command vm_program[MAX_PROGRAM_SIZE]; + +int vm_memory[MAX_MEMORY_SIZE]; +int vm_stack[MAX_STACK_SIZE]; + +unsigned int vm_stack_pointer = 0; +unsigned int vm_command_pointer = 0; + +opcode_info opcodes_table[] = { + {"NOP", 0}, + {"STOP", 0}, + {"LOAD", 1}, + {"STORE", 1}, + {"BLOAD", 1}, + {"BSTORE", 1}, + {"PUSH", 1}, + {"POP", 0}, + {"DUP", 0}, + {"INVERT", 0}, + {"ADD", 0}, + {"SUB", 0}, + {"MULT", 0}, + {"DIV", 0}, + {"COMPARE", 1}, + {"JUMP", 1}, + {"JUMP_YES", 1}, + {"JUMP_NO", 1}, + {"INPUT", 0}, + {"PRINT", 0} +}; + +int opcodes_table_size = sizeof(opcodes_table) / sizeof(opcode_info); + +typedef enum { + BAD_DATA_ADDRESS, + BAD_CODE_ADDRESS, + BAD_RELATION, + STACK_OVERFLOW, + STACK_EMPTY, + DIVISION_BY_ZERO, + BAD_INPUT, + UNKNOWN_COMMAND +} runtime_error; + +void vm_init() +{ + vm_stack_pointer = 0; + vm_command_pointer = 0; +} + +void vm_error(runtime_error error) +{ + opcode_info* info; + + switch(error) { + case BAD_DATA_ADDRESS: + fprintf(stderr, "Error: illegal data address\n"); + break; + + case BAD_CODE_ADDRESS: + fprintf(stderr, "Error: illegal address in JUMP* instruction\n"); + break; + + case BAD_RELATION: + fprintf(stderr, "Error: illegal comparison operator\n"); + break; + + case STACK_OVERFLOW: + fprintf(stderr, "Error: stack overflow\n"); + break; + + case STACK_EMPTY: + fprintf(stderr, "Error: stack is empty (no arguments are available)\n"); + break; + + case DIVISION_BY_ZERO: + fprintf(stderr, "Error: division by zero\n"); + break; + + case BAD_INPUT: + fprintf(stderr, "Error: illegal input\n"); + break; + + case UNKNOWN_COMMAND: + fprintf(stderr, "Error: unknown command, unable to execute\n"); + break; + + default: + fprintf(stderr, "Error: runtime error %d\n", error); + } + + fprintf(stderr, "Code:\n\n"); + + info = operation_info(vm_program[vm_command_pointer].operation); + if(NULL == info) { + fprintf(stderr, "%d\t(%d)\t\t%d\n", vm_command_pointer, + vm_program[vm_command_pointer].operation, + vm_program[vm_command_pointer].arg); + } + else { + if(info->need_arg) { + fprintf(stderr, "\t%d\t%s\t\t%d\n", vm_command_pointer, info->name, + vm_program[vm_command_pointer].arg); + } + else { + fprintf(stderr, "\t%d\t%s\n", vm_command_pointer, info->name); + } + } + + milan_error("VM error"); +} + +int vm_load(unsigned int address) +{ + if(address < MAX_MEMORY_SIZE) { + return vm_memory[address]; + } + else { + vm_error(BAD_DATA_ADDRESS); + return 0; + } +} + +void vm_store(unsigned int address, int word) +{ + if(address < MAX_MEMORY_SIZE) { + vm_memory[address] = word; + } + else { + vm_error(BAD_DATA_ADDRESS); + } +} + +int vm_read() +{ + int n; + + fprintf(stderr, "> "); fflush(stdout); + if(scanf("%d", &n)) { + return n; + } + else { + vm_error(BAD_INPUT); + return 0; + } +} + +void vm_write(int n) +{ + fprintf(stderr, "%d\n", n); +} + +int vm_pop() +{ + if(vm_stack_pointer > 0) { + return vm_stack[--vm_stack_pointer]; + } + else { + vm_error(STACK_EMPTY); + return 0; + } +} + +void vm_push(int word) +{ + if(vm_stack_pointer < MAX_STACK_SIZE) { + vm_stack[vm_stack_pointer++] = word; + } + else { + vm_error(STACK_OVERFLOW); + } +} + +int vm_run_command() +{ + unsigned int index = vm_command_pointer; + + operation op = vm_program[index].operation; + unsigned int arg = vm_program[index].arg; + int data; + + switch(op) { + case NOP: + /* Ничего не делаем */ + break; + + case STOP: + return 0; + break; + + case LOAD: + vm_push(vm_load(arg)); + break; + + case STORE: + vm_store(arg, vm_pop()); + break; + + case BLOAD: + vm_push(vm_load(arg + vm_pop())); + break; + + case BSTORE: + data = vm_pop(); + vm_store(arg + data, vm_pop()); + break; + + case PUSH: + vm_push(arg); + break; + + case POP: + vm_pop(); + break; + + case DUP: + data = vm_pop(); + vm_push(data); + vm_push(data); + break; + + case INVERT: + vm_push(-vm_pop()); + break; + + case ADD: + data = vm_pop(); + vm_push(vm_pop() + data); + break; + + case SUB: + data = vm_pop(); + vm_push(vm_pop() - data); + break; + + case MULT: + data = vm_pop(); + vm_push(vm_pop() * data); + break; + + case DIV: + data = vm_pop(); + if(0 == data) { + vm_error(DIVISION_BY_ZERO); + } + else { + vm_push(vm_pop() / data); + } + break; + + case COMPARE: + data = vm_pop(); + switch(arg) { + case EQ: + vm_push((vm_pop() == data) ? 1 : 0); + break; + + case NE: + vm_push((vm_pop() != data) ? 1 : 0); + break; + + case LT: + vm_push((vm_pop() < data) ? 1 : 0); + break; + + case GT: + vm_push((vm_pop() > data) ? 1 : 0); + break; + + case LE: + vm_push((vm_pop() <= data) ? 1 : 0); + break; + + case GE: + vm_push((vm_pop() >= data) ? 1 : 0); + break; + + default: + vm_error(BAD_RELATION); + } + break; + + case JUMP: + if(arg < MAX_PROGRAM_SIZE) { + vm_command_pointer = arg; + return 1; + } + else { + vm_error(BAD_CODE_ADDRESS); + } + + break; + + case JUMP_YES: + if(arg < MAX_PROGRAM_SIZE) { + data = vm_pop(); + if(data) { + vm_command_pointer = arg; + return 1; + } + } + else { + vm_error(BAD_CODE_ADDRESS); + } + break; + + case JUMP_NO: + if(arg < MAX_PROGRAM_SIZE) { + data = vm_pop(); + if(!data) { + vm_command_pointer = arg; + return 1; + } + } + else { + vm_error(BAD_CODE_ADDRESS); + } + break; + + case INPUT: + vm_push(vm_read()); + break; + + case PRINT: + vm_write(vm_pop()); + break; + + default: + vm_error(UNKNOWN_COMMAND); + } + + ++vm_command_pointer; + return 1; +} + +void run() +{ + vm_command_pointer = 0; + while(vm_command_pointer < MAX_PROGRAM_SIZE) { + if(!vm_run_command()) + break; + } +} + +opcode_info* operation_info(operation op) +{ + return (op < opcodes_table_size) ? &opcodes_table[op] : NULL; +} + +void put_command(unsigned int address, operation op, int arg) +{ + if(address < MAX_PROGRAM_SIZE) { + vm_program[address].operation = op; + vm_program[address].arg = arg; + } + else { + milan_error("Illegal address in put_command()"); + } +} + +void set_mem(unsigned int address, int value) +{ + vm_memory[address] = value; +} + diff --git a/lab4/vm/vm/vm.h b/lab4/vm/vm/vm.h new file mode 100644 index 0000000..9f444a1 --- /dev/null +++ b/lab4/vm/vm/vm.h @@ -0,0 +1,88 @@ +#ifndef _MILAN_VM_H +#define _MILAN_VM_H + +#include + +/* Константы */ + +/* Размер памяти команд */ +#define MAX_PROGRAM_SIZE 65536 + +/* Размер памяти данных */ +#define MAX_MEMORY_SIZE 65536 + +/* Размер стека */ +#define MAX_STACK_SIZE 8192 + +/* Команды виртуальной машины */ +typedef enum { + NOP = 0, /* Нет операции */ + STOP, /* Остановка */ + LOAD, /* Загрузка слова из памяти данных */ + STORE, /* Запись слова в память данных */ + BLOAD, /* Загрузка слова из памяти данных с учётом смещения */ + BSTORE, /* Запись слова в память данныз с учётом смещения */ + PUSH, /* Заталкивание слова в стек */ + POP, /* Выталкивание слова из стека */ + DUP, /* Дублирование слова на вершине стека */ + INVERT, /* Изменение знака числа на вершине стека */ + ADD, /* Сложение */ + SUB, /* Вычитание */ + MULT, /* Умножение */ + DIV, /* Целочисленное деление */ + COMPARE, /* Сравнение */ + JUMP, /* Безусловный переход */ + JUMP_YES, /* Условный переход, если на вершине стека не 0 */ + JUMP_NO, /* Условный переход, если на вершине стека 0 */ + INPUT, /* Чтение слова со стандартного устройства ввода */ + PRINT /* Запись слова на стандартное устройство вывода */ +} operation; + +/* Операции сравнения */ +typedef enum { + EQ, /* = */ + NE, /* !- */ + LT, /* < */ + GT, /* > */ + LE, /* <= */ + GE /* >= */ +} compare_type; + +/* Структура ячейки памяти команд */ +typedef struct { + operation operation; /* Код команды */ + int arg; /* Аргумент */ +} command; + +/* Информация о команде */ +typedef struct opcode_info { + char *name; /* Текстовое представление команды */ + int need_arg; /* Признак, равный 1, если команде нужен аргумент */ +} opcode_info; + +/* Получение информации о команде с кодом op. + * Освобождать память, на которую указывает возвращаемый + * указатель, не нужно. + */ + +opcode_info* operation_info(operation op); + +/* Запись команды в память команд по адресу address. */ + +void put_command(unsigned int address, operation op, int arg); + +/* Запуск программы. + * + * Исполнение программы начинается с адреса 0 и заканчивается, + * когда встретится команда STOP или будет обнаружена ошибка + * времени исполнения. + */ + +void run(); + +/* Запись значения value в память данных по адресу address. */ + +void set_mem(unsigned int address, int value); + +#endif + diff --git a/lab4/vm/vm/vmlex.l b/lab4/vm/vm/vmlex.l new file mode 100644 index 0000000..0ea8f88 --- /dev/null +++ b/lab4/vm/vm/vmlex.l @@ -0,0 +1,51 @@ +%{ +#include "vmparse.tab.h" +#include + +#ifndef __GNUC__ +#define YY_NO_UNISTD_H +#endif +%} + +%option noyywrap + +WHITESPACE [ \t]+ +EOL \n +INT -?[0-9]+ +COMMENT ;[^\n]*\n + +%% + +{EOL} +{COMMENT} +{WHITESPACE} +{INT} { yylval = atoi(yytext); return T_INT; } + +: { return T_COLON; } + +SET { return T_SET; } +STOP { return T_STOP; } +LOAD { return T_LOAD; } +STORE { return T_STORE; } +BLOAD { return T_BLOAD; } +BSTORE { return T_BSTORE; } +PUSH { return T_PUSH; } +POP { return T_POP; } +DUP { return T_DUP; } +INVERT { return T_INVERT; } +ADD { return T_ADD; } +SUB { return T_SUB; } +MULT { return T_MULT; } +DIV { return T_DIV; } +COMPARE { return T_COMPARE; } +JUMP { return T_JUMP; } +JUMP_YES { return T_JUMP_YES; } +JUMP_NO { return T_JUMP_NO; } +INPUT { return T_INPUT; } +PRINT { return T_PRINT; } +NOP { return T_NOP; } + +<> { yyterminate(); } + +%% + diff --git a/lab4/vm/vm/vmparse.tab.c b/lab4/vm/vm/vmparse.tab.c new file mode 100644 index 0000000..a703788 --- /dev/null +++ b/lab4/vm/vm/vmparse.tab.c @@ -0,0 +1,1736 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "vmparse.y" + +#include "vm.h" +#include +#include + +#define YYSTYPE int + +int yylex(); +void yyerror(char const *); + + +/* Line 189 of yacc.c */ +#line 85 "vmparse.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_INT = 258, + T_SET = 259, + T_NOP = 260, + T_STOP = 261, + T_LOAD = 262, + T_STORE = 263, + T_BLOAD = 264, + T_BSTORE = 265, + T_PUSH = 266, + T_POP = 267, + T_DUP = 268, + T_INVERT = 269, + T_ADD = 270, + T_SUB = 271, + T_MULT = 272, + T_DIV = 273, + T_COMPARE = 274, + T_JUMP = 275, + T_JUMP_YES = 276, + T_JUMP_NO = 277, + T_INPUT = 278, + T_PRINT = 279, + T_COLON = 280 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 152 "vmparse.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 7 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 37 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 26 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 3 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 24 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 39 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 280 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 6, 8, 12, 16, 21, 26, 31, + 36, 41, 45, 49, 53, 57, 61, 65, 69, 74, + 79, 84, 89, 93, 97 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 27, 0, -1, 28, 27, -1, 28, -1, 3, 25, + 5, -1, 3, 25, 6, -1, 3, 25, 7, 3, + -1, 3, 25, 8, 3, -1, 3, 25, 9, 3, + -1, 3, 25, 10, 3, -1, 3, 25, 11, 3, + -1, 3, 25, 12, -1, 3, 25, 13, -1, 3, + 25, 14, -1, 3, 25, 15, -1, 3, 25, 16, + -1, 3, 25, 17, -1, 3, 25, 18, -1, 3, + 25, 19, 3, -1, 3, 25, 20, 3, -1, 3, + 25, 21, 3, -1, 3, 25, 22, 3, -1, 3, + 25, 23, -1, 3, 25, 24, -1, 4, 3, 3, + -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 38, 38, 39, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "T_INT", "T_SET", "T_NOP", "T_STOP", + "T_LOAD", "T_STORE", "T_BLOAD", "T_BSTORE", "T_PUSH", "T_POP", "T_DUP", + "T_INVERT", "T_ADD", "T_SUB", "T_MULT", "T_DIV", "T_COMPARE", "T_JUMP", + "T_JUMP_YES", "T_JUMP_NO", "T_INPUT", "T_PRINT", "T_COLON", "$accept", + "program", "line", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 26, 27, 27, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 1, 3, 3, 4, 4, 4, 4, + 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 3, 3, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 3, 0, 0, 1, 2, 4, + 5, 0, 0, 0, 0, 0, 11, 12, 13, 14, + 15, 16, 17, 0, 0, 0, 0, 22, 23, 24, + 6, 7, 8, 9, 10, 18, 19, 20, 21 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 3, 4 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -6 +static const yytype_int8 yypact[] = +{ + 17, -3, 20, 24, 17, -5, 22, -6, -6, -6, + -6, 23, 25, 26, 27, 28, -6, -6, -6, -6, + -6, -6, -6, 29, 30, 31, 32, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -6, 33, -6 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 1, 2, 5, 6, 7, 29, 30, 0, 31, 32, + 33, 34, 35, 36, 37, 38, 0, 8 +}; + +static const yytype_int8 yycheck[] = +{ + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 3, 4, 25, 3, 0, 3, 3, -1, 3, 3, + 3, 3, 3, 3, 3, 3, -1, 4 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 4, 27, 28, 25, 3, 0, 27, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: + +/* Line 1455 of yacc.c */ +#line 42 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), NOP, 0); ;} + break; + + case 5: + +/* Line 1455 of yacc.c */ +#line 43 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), STOP, 0); ;} + break; + + case 6: + +/* Line 1455 of yacc.c */ +#line 44 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), LOAD, (yyvsp[(4) - (4)])); ;} + break; + + case 7: + +/* Line 1455 of yacc.c */ +#line 45 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), STORE, (yyvsp[(4) - (4)])); ;} + break; + + case 8: + +/* Line 1455 of yacc.c */ +#line 46 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), BLOAD, (yyvsp[(4) - (4)])); ;} + break; + + case 9: + +/* Line 1455 of yacc.c */ +#line 47 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), BSTORE, (yyvsp[(4) - (4)])); ;} + break; + + case 10: + +/* Line 1455 of yacc.c */ +#line 48 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), PUSH, (yyvsp[(4) - (4)])); ;} + break; + + case 11: + +/* Line 1455 of yacc.c */ +#line 49 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), POP, 0); ;} + break; + + case 12: + +/* Line 1455 of yacc.c */ +#line 50 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), DUP, 0); ;} + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 51 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), INVERT, 0); ;} + break; + + case 14: + +/* Line 1455 of yacc.c */ +#line 52 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), ADD, 0); ;} + break; + + case 15: + +/* Line 1455 of yacc.c */ +#line 53 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), SUB, 0); ;} + break; + + case 16: + +/* Line 1455 of yacc.c */ +#line 54 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), MULT, 0); ;} + break; + + case 17: + +/* Line 1455 of yacc.c */ +#line 55 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), DIV, 0); ;} + break; + + case 18: + +/* Line 1455 of yacc.c */ +#line 56 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), COMPARE, (yyvsp[(4) - (4)])); ;} + break; + + case 19: + +/* Line 1455 of yacc.c */ +#line 57 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), JUMP, (yyvsp[(4) - (4)])); ;} + break; + + case 20: + +/* Line 1455 of yacc.c */ +#line 58 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), JUMP_YES, (yyvsp[(4) - (4)])); ;} + break; + + case 21: + +/* Line 1455 of yacc.c */ +#line 59 "vmparse.y" + { put_command((yyvsp[(1) - (4)]), JUMP_NO, (yyvsp[(4) - (4)])); ;} + break; + + case 22: + +/* Line 1455 of yacc.c */ +#line 60 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), INPUT, 0); ;} + break; + + case 23: + +/* Line 1455 of yacc.c */ +#line 61 "vmparse.y" + { put_command((yyvsp[(1) - (3)]), PRINT, 0); ;} + break; + + case 24: + +/* Line 1455 of yacc.c */ +#line 62 "vmparse.y" + { set_mem((yyvsp[(2) - (3)]), (yyvsp[(3) - (3)])); ;} + break; + + + +/* Line 1455 of yacc.c */ +#line 1517 "vmparse.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 64 "vmparse.y" + + +void yyerror(char const *str) +{ + printf("Error: %s\n", str); +} + + diff --git a/lab4/vm/vm/vmparse.tab.h b/lab4/vm/vm/vmparse.tab.h new file mode 100644 index 0000000..79a4da0 --- /dev/null +++ b/lab4/vm/vm/vmparse.tab.h @@ -0,0 +1,79 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_INT = 258, + T_SET = 259, + T_NOP = 260, + T_STOP = 261, + T_LOAD = 262, + T_STORE = 263, + T_BLOAD = 264, + T_BSTORE = 265, + T_PUSH = 266, + T_POP = 267, + T_DUP = 268, + T_INVERT = 269, + T_ADD = 270, + T_SUB = 271, + T_MULT = 272, + T_DIV = 273, + T_COMPARE = 274, + T_JUMP = 275, + T_JUMP_YES = 276, + T_JUMP_NO = 277, + T_INPUT = 278, + T_PRINT = 279, + T_COLON = 280 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + + diff --git a/lab4/vm/vm/vmparse.y b/lab4/vm/vm/vmparse.y new file mode 100644 index 0000000..8d1fa79 --- /dev/null +++ b/lab4/vm/vm/vmparse.y @@ -0,0 +1,70 @@ +%{ +#include "vm.h" +#include +#include + +#define YYSTYPE int + +int yylex(); +void yyerror(char const *); +%} + +%token T_INT +%token T_SET +%token T_NOP +%token T_STOP +%token T_LOAD +%token T_STORE +%token T_BLOAD +%token T_BSTORE +%token T_PUSH +%token T_POP +%token T_DUP +%token T_INVERT +%token T_ADD +%token T_SUB +%token T_MULT +%token T_DIV +%token T_COMPARE +%token T_JUMP +%token T_JUMP_YES +%token T_JUMP_NO +%token T_INPUT +%token T_PRINT +%token T_COLON + +%% + +program : line program + | line + ; + +line : T_INT T_COLON T_NOP { put_command($1, NOP, 0); } + | T_INT T_COLON T_STOP { put_command($1, STOP, 0); } + | T_INT T_COLON T_LOAD T_INT { put_command($1, LOAD, $4); } + | T_INT T_COLON T_STORE T_INT { put_command($1, STORE, $4); } + | T_INT T_COLON T_BLOAD T_INT { put_command($1, BLOAD, $4); } + | T_INT T_COLON T_BSTORE T_INT { put_command($1, BSTORE, $4); } + | T_INT T_COLON T_PUSH T_INT { put_command($1, PUSH, $4); } + | T_INT T_COLON T_POP { put_command($1, POP, 0); } + | T_INT T_COLON T_DUP { put_command($1, DUP, 0); } + | T_INT T_COLON T_INVERT { put_command($1, INVERT, 0); } + | T_INT T_COLON T_ADD { put_command($1, ADD, 0); } + | T_INT T_COLON T_SUB { put_command($1, SUB, 0); } + | T_INT T_COLON T_MULT { put_command($1, MULT, 0); } + | T_INT T_COLON T_DIV { put_command($1, DIV, 0); } + | T_INT T_COLON T_COMPARE T_INT { put_command($1, COMPARE, $4); } + | T_INT T_COLON T_JUMP T_INT { put_command($1, JUMP, $4); } + | T_INT T_COLON T_JUMP_YES T_INT { put_command($1, JUMP_YES, $4); } + | T_INT T_COLON T_JUMP_NO T_INT { put_command($1, JUMP_NO, $4); } + | T_INT T_COLON T_INPUT { put_command($1, INPUT, 0); } + | T_INT T_COLON T_PRINT { put_command($1, PRINT, 0); } + | T_SET T_INT T_INT { set_mem($2, $3); } + ; +%% + +void yyerror(char const *str) +{ + printf("Error: %s\n", str); +} +