Автор работы: Пользователь скрыл имя, 02 Апреля 2013 в 23:51, курсовая работа
Целью данной курсовой работы являлось изучение составных частей, основных принципов построения и функционирования компиляторов, практическое освоение методов построения простейших компиляторов для заданного входного языка.
Введение 2
1 Организация таблицы идентификаторов 3
1.1 Исходные данные 3
1.2 Назначение таблиц идентификаторов 3
1.3 Метод цепочек 3
1.4 Метод бинарного дерева 7
1.5 Результаты 9
2 Проектирование лексического анализатора 10
2.1 Исходные данные 10
2.2 Принципы работы лексических анализаторов 10
2.3 Схема распознавателя 11
2.4 Результаты 12
3 Построение дерева вывода 13
3.1 Исходные данные 13
3.2 Синтаксический анализатор 13
3.3 Результаты 17
Заключение 19
Список использованных источников 20
Приложение А. Граф состояний лексического анализатора 21
Приложение Б. Матрица операторного предшествования 22
Приложение В. Исходный текст программы 23
break;
case I:
string="I";
break;
case IF:
string="IF";
break;
case T:
string="T";
break;
case TH:
string="TH";
break;
case THE:
string="THE";
break;
case THEN:
string="THEN";
break;
case B:
string="B";
break;
case BE:
string="BE";
break;
case BEG:
string="BEG";
break;
case BEGI:
string="BEGI";
break;
case BEGIN:
string="BEGIN";
break;
case A:
string="A";
break;
case AN:
string="AN";
break;
case AND:
string="AND";
break;
case O:
string="O";
break;
case OR:
string="OR";
break;
case N:
string="N";
break;
case NO:
string="NO";
break;
case NOT:
string="NOT";
break;
case LBRACKET:
string="LBRACKET";
break;
case COMMENT:
string="COMMENT";
break;
case RBRACKET:
string="RBRACKET";
break;
case ADD:
string="ADD";
break;
case SUB:
string="SUB";
break;
case EQUAL:
string="EQUAL";
break;
case LESS:
string="LESS";
break;
case NONEQUAL:
string="NONEQUAL";
break;
case LSHIFT:
string="LSHIFT";
break;
case MORE:
string="MORE";
break;
case RSHIFT:
string="RSHIFT";
break;
case TWOSPOT:
string="TWOSPOT";
break;
case ASSIGN:
string="ASSIGN";
break;
case FINITE:
string="FINITE";
break;
case LASTER:
string="LASTER";
break;
case RASTER:
string="RASTER";
break;
case STOP:
string="STOP";
break;
case F:
string="F";
break;
case FO:
string="FO";
break;
case FOR:
string="FOR";
break;
case D:
string="D";
break;
case DO:
string="DO";
break;
case DOW:
string="DOW";
break;
case DOWN:
string="DOWN";
break;
case DOWNT:
string="DOWNT";
break;
case DOWNTO:
string="DOWNTO";
break;
}
return string;
}
//Описание конечных состояний
QString LexFSM::finiteStateString(
{
QString string="";
switch(name)
{
case ID:
string=tr("Переменная");
break;
case CONSTANT:
string=tr("Константа");
break;
case SEPARATOR:
string=tr("Разделитель");
break;
case PROGRAM:
string=tr("Ключевое слово 'program'");
break;
case END:
string=tr("Ключевое слово 'end'");
break;
case ENDD:
string=tr("Ключевое слово 'end.'");
break;
case ENDIF:
string=tr("Ключевое слово 'endif'");
break;
case ELSE:
string=tr("Ключевое слово 'else'");
break;
case IF:
string=tr("Ключевое слово 'if'");
break;
case THEN:
string=tr("Ключевое слово 'then'");
break;
case BEGIN:
string=tr("Ключевое слово 'begin'");
break;
case AND:
string=tr("Ключевое слово 'and'");
break;
case OR:
string=tr("Ключевое слово 'or'");
break;
case NOT:
string=tr("Ключевое слово 'not'");
break;
case LBRACKET:
string=tr("Открывающая скобка");
break;
case RBRACKET:
string=tr("Закрывающая скобка");
break;
case ADD:
string=tr("Знак операции '+'");
break;
case SUB:
string=tr("Знак операции '-'");
break;
case EQUAL:
string=tr("Знак операции '='");
break;
case LESS:
string=tr("Знак операции '<'");
break;
case NONEQUAL:
string=tr("Знак операции '<>'");
break;
case LSHIFT:
string=tr("Оператор сдвига влево '<<'");
break;
case MORE:
string=tr("Знак операции '>'");
break;
case RSHIFT:
string=tr("Оператор сдвига вправо '>>'");
break;
case ASSIGN:
string=tr("Оператор присваивания ':='");
break;
case FOR:
string=tr("Ключевое слово 'for'");
break;
case DOWNTO:
string=tr("Ключевое слово 'downto'");
break;
case DO:
string=tr("Ключевое слово 'do'");
break;
}
return string;
}
//Обработка очередного входного символа
void LexFSM::analyseNextChar(QChar c)
{
emit sendLog(tr("Обработка символа '%1'").arg(c), "EVENT");
cReserved=c; //запоминание символа
if (c==QChar(65534)) //Если конец файла
{
setNextState(STOP); //остановить автомат
return;
}
switch(state) //если текущее состояние...
{
case START:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(START);
else if (c=='p')
setNextState(P);
else if (c=='e')
setNextState(E);
else if (c=='i')
setNextState(I);
else if (c=='t')
setNextState(T);
else if (c=='b')
setNextState(B);
else if (c=='a')
setNextState(A);
else if (c=='o')
setNextState(O);
else if (c=='n')
setNextState(N);
else if (c=='f')
setNextState(F);
else if (c=='d')
setNextState(D);
else if (c=='(')
setNextState(LBRACKET);
else if (c==')')
setNextState(RBRACKET);
else if (c==';')
setNextState(SEPARATOR);
else if (c=='+')
setNextState(ADD);
else if (c=='-')
setNextState(SUB);
else if (c=='=')
setNextState(EQUAL);
else if (c=='<')
setNextState(LESS);
else if (c=='>')
setNextState(MORE);
else if (c==':')
setNextState(TWOSPOT);
else if (('0'==c) || (c=='1'))
setNextState(CONSTANT);
else if (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')) || (c=='_'))
setNextState(ID);
else
setNextState(ERROR);
break;
case ID:
if (((c>='0') && (c<='9')) || ((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')) || (c=='_'))
setNextState(ID);
else if (idFiniteList.contains(c))
setNextState(FINITE);
else
setNextState(ERROR);
break;
case SEPARATOR:
setNextState(FINITE);
break;
case CONSTANT:
if ((c=='0') || (c=='1'))
setNextState(CONSTANT);
else if ((c==':') || ((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')))
setNextState(ERROR);
else
setNextState(FINITE);
case COMMENT:
setNextState(FINITE);
break;
case P:
if (c=='r')
setNextState(PR);
else
setNextState(ID);
break;
case PR:
if (c=='o')
setNextState(PRO);
else
setNextState(ID);
break;
case PRO:
if (c=='g')
setNextState(PROG);
else
setNextState(ID);
break;
case PROG:
if (c=='r')
setNextState(PROGR);
else
setNextState(ID);
break;
case PROGR:
if (c=='a')
setNextState(PROGRA);
else
setNextState(ID);
break;
case PROGRA:
if (c=='m')
setNextState(PROGRAM);
else
setNextState(ID);
break;
case PROGRAM:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case E:
if (c=='n')
setNextState(EN);
else if (c=='l')
setNextState(EL);
else
setNextState(ID);
break;
case EN:
if (c=='d')
setNextState(END);
else
setNextState(ID);
break;
case END:
if ((c==' ') || (c=='\n') || (c=='\0') || (c==';'))
setNextState(FINITE);
else if (c=='.')
setNextState(ENDD);
else if (c=='i')
setNextState(ENDI);
else
setNextState(ID);
break;
case ENDD:
if ((c==' ') || (c=='\n') || (c=='\0') || (c==QChar(65534)))
setNextState(FINITE);
else
setNextState(ID);
break;
case ENDI:
if (c=='f')
setNextState(ENDIF);
else
setNextState(ID);
break;
case ENDIF:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case EL:
if (c=='s')
setNextState(ELS);
else
setNextState(ID);
break;
case ELS:
if (c=='e')
setNextState(ELSE);
else
setNextState(ID);
break;
case ELSE:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case I:
if (c=='f')
setNextState(IF);
else
setNextState(ID);
break;
case IF:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case T:
if (c=='h')
setNextState(TH);
else
setNextState(ID);
break;
case TH:
if (c=='e')
setNextState(THE);
else
setNextState(ID);
break;
case THE:
if (c=='n')
setNextState(THEN);
else
setNextState(ID);
break;
case THEN:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case B:
if (c=='e')
setNextState(BE);
else
setNextState(ID);
break;
case BE:
if (c=='g')
setNextState(BEG);
else
setNextState(ID);
break;
case BEG:
if (c=='i')
setNextState(BEGI);
else
setNextState(ID);
break;
case BEGI:
if (c=='n')
setNextState(BEGIN);
else
setNextState(ID);
break;
case BEGIN:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case A:
if (c=='n')
setNextState(AN);
else
setNextState(ID);
break;
case AN:
if (c=='d')
setNextState(AND);
else
setNextState(ID);
break;
case AND:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case O:
if (c=='r')
setNextState(OR);
else
setNextState(ID);
break;
case OR:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case N:
if (c=='o')
setNextState(NO);
else
setNextState(ID);
break;
case NO:
if (c=='t')
setNextState(NOT);
else
setNextState(ID);
break;
case NOT:
case LBRACKET:
if (c=='*')
setNextState(LASTER);
else
setNextState(FINITE);
break;
case LASTER:
if (c=='*')
setNextState(RASTER);
else
setNextState(LASTER);
break;
case RASTER:
if (c==')')
setNextState(COMMENT);
else
setNextState(LASTER);
break;
case RBRACKET:
setNextState(FINITE);
break;
case ADD:
setNextState(FINITE);
break;
case SUB:
setNextState(FINITE);
break;
case EQUAL:
setNextState(FINITE);
break;
case LESS:
if (c=='>')
setNextState(NONEQUAL);
else if(c=='<')
setNextState(LSHIFT);
else
setNextState(FINITE);
break;
case NONEQUAL:
setNextState(FINITE);
break;
case LSHIFT:
setNextState(FINITE);
break;
case MORE:
if (c=='>')
setNextState(RSHIFT);
else
setNextState(FINITE);
break;
case RSHIFT:
setNextState(FINITE);
break;
case TWOSPOT:
if (c=='=')
setNextState(ASSIGN);
else
setNextState(ERROR);
break;
case ASSIGN:
setNextState(FINITE);
break;
case F:
if (c=='o')
setNextState(FO);
else
setNextState(ID);
break;
case FO:
if (c=='r')
setNextState(FOR);
else
setNextState(ID);
break;
case FOR:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case D:
if (c=='o')
setNextState(DO);
else
setNextState(ID);
break;
case DO:
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else if (c=='w')
setNextState(DOW);
else
setNextState(ID);
break;
case DOW:
if ((c=='n'))
setNextState(DOWN);
else
setNextState(ID);
break;
case DOWN:
if (c=='t')
setNextState(DOWNT);
else
setNextState(ID);
break;
case DOWNT:
if (c=='o')
setNextState(DOWNTO);
else
setNextState(ID);
break;
case DOWNTO :
if ((c==' ') || (c=='\n') || (c=='\0'))
setNextState(FINITE);
else
setNextState(ID);
break;
case ERROR:
setNextState(ERROR);
break;
case STOP:
setNextState(STOP);
break;
default:
setNextState(ERROR);
break;
}
}
LexAnalyser.h
#ifndef LEXANALYSER_H
#define LEXANALYSER_H
#include <QFile>
#include <QTextStream>
#include <QObject>
#include <QVector>
#include <QMap>
#include "LexFSM.h"
class LexAnalyser : public QObject
{
Q_OBJECT
public:
LexAnalyser(QObject* parent = 0);
void analyseNextCharacter(QChar c);
void readFile(QString);
private:
struct lexemeDescription
{
QString text;
QString type;
int stringNumber;
};
lexemeDescription lexDesc;
LexFSM::stateName state;
QVector<lexemeDescription> lexemes;
QMap<QString, int> identifiers;
int identifiersCnt;
QFile file;
QTextStream in;
bool flagEOF;
QString readString();
QString line;
int stringNumber;
signals:
void sendLog(QString, QString);
void setNextChar(QChar);
void setRedLine(int);
void fileSuccessfullyOpened();
void endOfFile();
void showLexeme(QString, QString, QString num=0);
void sendLexemes(QVector<
void sendIdentifiers(QMap<QString, int>);
private slots:
void setError();
void readChar();
void addLexeme(QString, QString, QString);
};
#endif //LEXANALYSER_H
LexAnalyser.cpp
#include "LexAnalyser.h"
#include "LexFSM.h"
#include <QMessageBox>
#include <QChar>
//Лексический анализатор
LexAnalyser::LexAnalyser(
: QObject(parent)
{
stringNumber=0;
flagEOF=0;
identifiersCnt=0;
}
void LexAnalyser::readFile(QString fileName)
{
// file.close();
emit sendLog(tr("Открытие файла %1").arg(fileName), "MESSAGE");
flagEOF=0; //флаг конца файла
stringNumber=0;
file.setFileName(fileName);
if (!file.open(QIODevice::
QMessageBox::critical(0, "Error", "Can't open file for read", "OK");
in.setDevice(&file);
emit fileSuccessfullyOpened(); //сообщаем об открытии файла
}
//чтение очередной строки из файла
QString LexAnalyser::readString()
{
line=""; //обнуление строки
if (!in.atEnd()) //если не конец файла
{
stringNumber++; //номер строки
emit sendLog(tr("Чтение строки %1").arg(stringNumber), "MESSAGE");
line=in.readLine().simplified(
}
else //конец файла
{
emit sendLog(tr("Чтение файла закончено"), "END");
file.close(); //закрытие файла
flagEOF=1; //флаг конца файла
}
return line;
}
//чтение очередного символа из строки
void LexAnalyser::readChar()
{
if (!line.isEmpty()) //если строка не пуста
{
QChar c=line[0];
line.remove(0, 1); //удаляем прочитанный символ в строке
emit setNextChar(c); //посылаем символ автомату
}
else //строка пуста
{
//читаем новую строку
line=readString();
if (flagEOF) //флаг конца файла
{
emit endOfFile(); //сообщить, что достигнут конец файла
emit setNextChar(QChar(65534)); //послать автомату символ, говорящий, что достигнут конец файла
emit sendLexemes(lexemes); //послать лексемы синтаксическому анализатору
sendLog(tr("Отправлены
лексемы синтаксическому
emit sendIdentifiers(identifiers); //послать идентификаторы синтаксическому анализатору
sendLog(tr("Отправлены
идентификаторы
}
else //не конец файла
emit setNextChar('\0'); //послать символ, говорящий, что достигнут конец текущей строки
}
}
//сообщить об ошибке
void LexAnalyser::setError()
{
QMessageBox::critical(0, "ERROR", tr("Лексическая ошибка в %1 строке").arg(stringNumber), "OK");
emit sendLog(tr("Лексическая ошибка в %1 строке").arg(stringNumber), "ERROR");
emit setRedLine(stringNumber);
emit sendLog(tr("Чтение файла закончено"), "END");
file.close(); //закрытие файла
in.readAll();
flagEOF=1; //флаг конца файла
}
//добавить
лексему в таблицу
void LexAnalyser::addLexeme(QString text, QString stateString, QString type)
{
if (stateString==tr("Переменная")
{
if (!identifiers.contains(text)) //если данный идентификатор встречается первый раз
{
identifiersCnt++; //счетчик идентификаторов
identifiers.insert(text, identifiersCnt); //добавление идентификатора в таблицу идентификаторов
}
QString str;
str.setNum(identifiers.value(
emit showLexeme(text, stateString, str); //послать лексему в таблицу
}
else
emit showLexeme(text, stateString); //послать лексему в таблицу
lexDesc.text=text; //текст
lexDesc.type=type; //тип лексемы
lexDesc.stringNumber=
lexemes.append(lexDesc); //
}
SynAnalyser.h
#ifndef SYNANALYSER_H
#define SYNANALYSER_H
#define RULENUM 29
#define MAXRULELENGTH 300
#include <QObject>
#include <QVector>
#include <QMap>
#include <QStack>
#include <QChar>
class SynAnalyser : public QObject
{
Q_OBJECT
public:
SynAnalyser(QObject* parent = 0);
private:
struct lexemeDescription