Проектирование лексического анализатора

Автор работы: Пользователь скрыл имя, 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

Вложенные файлы: 5 файлов

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА.doc

— 148.00 Кб (Просмотреть документ, Скачать файл)

Приложение А.doc

— 109.50 Кб (Просмотреть документ, Скачать файл)

Приложение Б.doc

— 152.00 Кб (Просмотреть документ, Скачать файл)

Приложение В.doc

— 256.00 Кб (Скачать файл)

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(LexFSM::stateName name)

{

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<lexemeDescription>);

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)

: 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::ReadOnly | QIODevice::Text)) //открываем файл на чтение

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("Отправлены  лексемы синтаксическому анализатору"), "MESSAGE");

emit sendIdentifiers(identifiers); //послать идентификаторы синтаксическому анализатору

sendLog(tr("Отправлены  идентификаторы синтаксическому  анализатору"), "MESSAGE");

}

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(text));

emit showLexeme(text, stateString, str); //послать лексему в таблицу

}

else

emit showLexeme(text, stateString); //послать лексему в таблицу

lexDesc.text=text; //текст

lexDesc.type=type; //тип лексемы

lexDesc.stringNumber=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

Информация о работе Проектирование лексического анализатора