Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовой проект3 / Приложение В.doc
Скачиваний:
33
Добавлен:
02.05.2014
Размер:
262.14 Кб
Скачать

If (!file.Open(qioDevice::ReadOnly | qioDevice::Text))

QMessageBox::critical(0, "Error", "Cannot open file for read: %1", "OK");

QTextStream in(&file);

while (!in.atEnd()) //пока не конец

{

QString line = in.readLine(); //считываем очередную строку

findText(line); //ищем строку в ТИ

}

}

LexFSM.h

#ifndef LEXFSM_H

#define LEXFSM_H

#include <QObject>

#include <QString>

#include <QMap>

class QList;

class LexFSM : public QObject

{

Q_OBJECT

public:

LexFSM();

enum stateName

{

START, //начальное состояние

ID, //переменная

CONSTANT, //константа

SEPARATOR, //разделитель (;)

ERROR,

P, PR, PRO, PROG, PROGR, PROGRA, PROGRAM, //program

E, EN, END, //end

ENDD, //end.

ENDI, ENDIF, //endif

EL, ELS, ELSE, //else

I, IF, //if

T, TH, THE, THEN, //then

B, BE, BEG, BEGI, BEGIN, //begin

A, AN, AND, //and

O, OR, //or

N, NO, NOT, //NOT

LBRACKET, // (

LASTER, RASTER, COMMENT, //комментарий (* *)

RBRACKET, // )

ADD, // +

SUB, // -

EQUAL, // =

LESS, // <

NONEQUAL, // <>

LSHIFT, // << - дополнительная операция

MORE, // >

RSHIFT, // >> - дополнительная операция

TWOSPOT, ASSIGN, // :=

FINITE, //конечное состояние

STOP,

//дополнительные состояния, соответствующие варианту задания

F, FO, FOR, //for

D, DO, //do

DOW, DOWN,DOWNT, DOWNTO //downto

};

private:

QChar cReserved;

QString lexeme;

stateName state;

void setNextState(stateName);

QString stateString(LexFSM::stateName name);

QString finiteStateString(LexFSM::stateName name);

QList<QChar> idFiniteList;

private slots:

void startFSM();

void analyseNextChar(QChar c);

signals:

void getNextChar();

void lexError();

void addNewTableItem(QString);

void setAddLexeme(QString, QString, QString type);

void sendLog(QString text, QString description);

};

#endif

LexFSM.cpp

#include "LexFSM.h"

#include <QFile>

#include <QMessageBox>

#include <QTextStream>

#include <QChar>

#include <QList>

//Конечный автомат

LexFSM::LexFSM()

{

emit sendLog(tr("Модуль LexFSM подключен"), "MESSAGE");

state=START;

}

//Запуск автомата

void LexFSM::startFSM()

{

//Допустимые символы, следующие за переменными

idFiniteList<<' '<<'\n'<<'\0'<<':'<<';'<<'('<<')'<<'>'<<'<'<<'+'<<'-'<<'=';

state=START;

emit sendLog(tr("Начало работы лексического анализатора"), "END");

emit sendLog(tr("Запуск конечного автомата"), "END");

getNextChar();//Запросить входной символ

}

//Переход в новое состояние

void LexFSM::setNextState(LexFSM::stateName nextState)

{

if (state==STOP) //Если автомат остановлен, стоять

{

}

else

{

emit sendLog(tr("Переход из состояния %1 в %2").arg(stateString(state)).arg(stateString(nextState)), "EVENT");

if (nextState==STOP)//Остановка автомата

{

lexeme=lexeme.remove(QChar('\0'));

lexeme=lexeme.remove(QChar(65534));

if (!lexeme.simplified().isEmpty())

emit setAddLexeme(lexeme.simplified(), finiteStateString(state), stateString(state));

state=STOP;

emit sendLog(tr("Остановка конечного автомата"), "END");

emit sendLog(tr("Выполнение лексического анализа успешно завершено"), "END");

}

else if (nextState==FINITE) //Если конечное состояние

{

lexeme=lexeme.remove(QChar('\0'));

if (state==COMMENT) //Если обнаружен комментарий

{

emit sendLog(tr("Проигнорирован комментарий: %1").arg(lexeme.simplified()), "COMMENT");

lexeme="";

}

else if (state==CONSTANT)

{

bool constOk;

int cst=lexeme.simplified().toInt(&constOk, 2);

if ((!constOk) || (cst<0) || (cst>255))

{

QMessageBox::critical(0, "CONSTANT ERROR", tr("Ошибочная константа %1!\nКонстанты типа Byte - это беззнаковое целое от 0 до 255!").arg(cst), "OK");

setNextState(ERROR);

return;

}

else

{

emit setAddLexeme(lexeme.simplified(), finiteStateString(state), stateString(state));

emit sendLog(tr("Добавление новой строки: %1 (%2)").arg(lexeme.simplified()).arg(finiteStateString(state)), "END");

lexeme="";

}

}

else //Обнаружена новая лексема

{

emit setAddLexeme(lexeme.simplified(), finiteStateString(state), stateString(state));

emit sendLog(tr("Добавление новой строки: %1 (%2, %3)").arg(lexeme.simplified()).arg(finiteStateString(state)).arg(stateString(state)), "END");

lexeme="";

}

state=START; //Сброс автомата в начальное состояние

emit sendLog(tr("Новое состояние: %1").arg(stateString(state)), "MESSAGE");

analyseNextChar(cReserved); //Повторный анализ символа, приведшего в переходу в конечное состояние

}

else if ((state!=nextState) && (nextState==ID)) //переход в состояние идентификатора

{

state=ID;

emit sendLog(tr("Новое состояние: %1").arg(stateString(state)), "MESSAGE");

analyseNextChar(cReserved);

}

else if (nextState==ERROR) //Ошибка

{

emit sendLog(tr("Лексическая ошибка!"), "ERROR");

emit lexError();

state=ERROR;

emit sendLog(tr("Новое состояние: %1").arg(stateString(state)), "MESSAGE");

setNextState(STOP);

}

else //Обычный переход

{

lexeme.append(cReserved); //добавление символа в цепочку

state=nextState;

emit sendLog(tr("Новое состояние: %1").arg(stateString(state)), "MESSAGE");

emit getNextChar();//Запросить следующий символ

}

}

}

//Названия состояний, использующиеся для лога

QString LexFSM::stateString(LexFSM::stateName name)

{

QString string="";

switch(name)

{

case START:

string="START";

break;

case ID:

string="ID";

break;

case CONSTANT:

string="CONSTANT";

break;

case SEPARATOR:

string="SEPARATOR";

break;

case ERROR:

string="ERROR";

break;

case P:

string="P";

break;

case PR:

string="PR";

break;

case PRO:

string="PRO";

break;

case PROG:

string="PROG";

break;

case PROGR:

string="PROGR";

break;

case PROGRA:

string="PROGRA";

break;

case PROGRAM:

string="PROGRAM";

break;

case E:

string="E";

break;

case EN:

string="EN";

break;

case END:

string="END";

break;

case ENDD:

string="ENDD";

break;

case ENDI:

string="ENDI";

break;

case ENDIF:

string="ENDIF";

break;

case EL:

string="EL";

break;

case ELS:

string="ELS";

break;

case ELSE:

string="ELSE";

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

Соседние файлы в папке Курсовой проект3