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

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

{

QString text;

QString type;

int stringNumber;

};

struct synTreeItem

{

QString text;

QVector<synTreeItem*> childItems;

};

struct stackItem

{

QString text;

QString value;

synTreeItem* node;

};

synTreeItem* rootTreeItem;

synTreeItem* treeItem;

synTreeItem* treeItemChild;

QChar matrix[29][29];

QString rules[29];

lexemeDescription lexDesc;

QVector<lexemeDescription> lexemes;

QMap<QString, int> identifiers;

QStack<stackItem> stack;

stackItem sItem;

int stackSize;

int lexemesPos;

int stackPos;

void createMatrix();

void createRules();

int maxRuleLength;

void start();

QChar getMatrixValue(QString tTerm, QString fLex);

void shift(); //сдвиг

void reduce(); //свертка

QString getTopTerm();

int getTermNum(QString text);

QString topTerm;

QString curLex;

QString curRule;

QString SynAnalyser::getStackItemText();

signals:

void sendLog(QString, QString);

void setRedLine(int);

void setRootItem(synTreeItem*);

private slots:

void setError(int stringNumber);

void getLexemes(QVector<lexemeDescription>);

void getIdentifiers(QMap<QString, int>);

};

#endif //SYNANALYSER_H

SynAnalyser.cpp

#include "SynAnalyser.h"

#include <QMessageBox>

//Лексический анализатор

SynAnalyser::SynAnalyser(QObject* parent)

: QObject(parent)

{

createMatrix();

createRules();

}

//заполнение матрицы операторного предшествования

void SynAnalyser::createMatrix()

{

QChar matrixEx[29][29] = {

// 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 26 27 28 29

/*1 program*/{' ', '=', '<', '<', ' ', ' ', ' ', '<', ' ', '<', ' ', ' ', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*2 end.*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},

/*3 ;*/ {' ', '>', '>', '<', ' ', ' ', ' ', '<', '>', '<', ' ', ' ', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*4 if*/ {' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '<', '<', '<', '<', '<', '<', '<', '<', ' ', '<', '<', '<', '<', ' '},

/*5 then*/ {' ', ' ', ' ', '<', ' ', '=', '=', '<', ' ', '<', ' ', ' ', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*6 else*/ {' ', ' ', ' ', '<', ' ', ' ', '=', '<', ' ', '<', ' ', ' ', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*7 endif*/ {' ', '>', '>', ' ', ' ', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*8 begin*/ {' ', ' ', '<', '<', ' ', ' ', ' ', '<', '=', '<', ' ', ' ', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*9 end*/ {' ', '>', '>', ' ', ' ', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*10 for*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '=', ' ', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*11 downto*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', ' ', ' ', '=', '<', '<', ' ', ' ', ' ', ' ', '<', '<', '<', '<', '<', ' ', '<', '<', '<', '<', ' '},

/*12 do */ {' ', '>', '>', '<', ' ', '>', '>', '<', '>', ' ', ' ', ' ', '<', ' ', ' ', ' ', ' ', ' ', '<', '<', '<', '<', '<', ' ', '<', '<', '<', '<', ' '},

/*13 a*/ {' ', '>', '>', ' ', '>', '>', '>', ' ', '>', ' ', '>', '>', ' ', ' ', '=', '>', ' ', ' ', '>', '>', '>', '>', ' ', '>', '>', '>', ' ', ' ', ' '},

/*14 c*/ {' ', '>', '>', ' ', '>', '>', '>', ' ', '>', ' ', '>', '>', ' ', ' ', ' ', '>', ' ', ' ', '>', '>', '>', '>', ' ', '>', '>', '>', ' ', ' ', ' '},

/*15 :=*/ {' ', '>', '>', ' ', ' ', '>', '>', ' ', ' ', ' ', '>', ' ', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', ' ', '<', '<', ' ', ' ', ' '},

/*16 or*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '<', '<', '<', '<', '<', '<', '<', '>', '<', '<', '<', '<', ' '},

/*17 and*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '<', '<', '<', '<', '<', '<', '<', '>', '<', '<', '<', '<', ' '},

/*18 not*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', '<', '<', '<', '<', '<', '<', '>', '<', '<', '<', '<', ' '},

/*19 <*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', ' ', ' ', ' ', ' ', ' ', '<', '>', '<', '<', ' ', ' ', ' '},

/*20 >*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', ' ', ' ', ' ', ' ', ' ', '<', '>', '<', '<', ' ', ' ', ' '},

/*21 =*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', ' ', ' ', ' ', ' ', ' ', '<', '>', '<', '<', ' ', ' ', ' '},

/*22 <>*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', ' ', ' ', ' ', ' ', ' ', '<', '>', '<', '<', ' ', ' ', ' '},

/*23 (*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '<', '<', '<', '<', '<', '<', '<', '<', ' ', '<', '<', '<', '<', ' '},

/*24 )*/ {' ', '>', '>', ' ', '>', '>', '>', ' ', '>', ' ', '>', '>', ' ', ' ', ' ', '>', '>', ' ', '>', '>', '>', '>', ' ', '>', '>', '>', ' ', ' ', ' '},

/*25 -*/ {' ', '>', '>', ' ', '>', '>', '>', ' ', '>', ' ', '>', '>', '<', '<', ' ', '>', '>', ' ', '>', '>', '>', '>', '<', '>', '>', '>', ' ', ' ', ' '},

/*26 +*/ {' ', '>', '>', ' ', '>', '>', '>', ' ', '>', ' ', '>', '>', '<', '<', ' ', '>', '>', ' ', '>', '>', '>', '>', '<', '>', '>', '>', ' ', ' ', ' '},

/*27 <<*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*28 >>*/ {' ', ' ', ' ', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', ' ', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},

/*29 _|_н*/ {'<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}

};

for (int i=0; i<29; i++)

{

for (int j=0; j<29; j++)

{

matrix[i][j] = matrixEx[i][j];

}

}

}

//Правила исходной грамматики

void SynAnalyser::createRules()

{ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

QString rulesEx[29] = {"programEend.", "E", "E;E", "E;", "ifBthenEelseEendif", "ifBthenEendif", "beginEend", "forEdowntoEdoE", "E","a:=E", "E-E", "E+E", "E", "(E)", "a", "c",//правила E->...

// 16 17 18 19 20 21 22 23 24 25 26 27 28

"BorB", "B", "BandB", "B", "notB", "B", "E<E", "E>E", "E=E", "E<>E", "(B)", "E<<E", "E>>E" //правила B->...

};

for (int i=0; i<29; i++)

rules[i] = rulesEx[i];

}

//алгоритм сдвиг-свертка

void SynAnalyser::start()

{

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

sendLog(tr("Количество лексем: %1").arg(lexemes.size()), "EVENT");

rootTreeItem = new synTreeItem; //корневой узел дерева

int lexemesPos=0; //позиция в цепочке лексем

int stackPos=0; //позиция в стеке

int flag=0; //флаг завершения алгоритма

stack.clear(); //очистка стека

stackSize=0; //размер стека

sItem.text="["; //маркер начала строки

sItem.value="[";

stack.push(sItem); //добавляем в стек маркер начала строки

stackSize++;

sendLog(tr("В стек добавлен маркер начала строки"), "EVENT");

lexDesc.text="]"; //маркер конца строки

lexDesc.type="LINEEND";

lexemes.append(lexDesc); //добавить в конец входной цепочки маркер конца строки

sendLog(tr("В конец входной цепочки добавлен маркер конца строки"), "EVENT");

while (flag==0)

{

topTerm = getTopTerm(); //верхний терминал стека

sendLog(tr("Верхний терминал стека: %1").arg(topTerm), "EVENT");

lexDesc = lexemes.at(lexemesPos); //считываем очередную лексему

curLex = lexDesc.text; //текущий символ входной цепочки

sendLog(tr("Текущий символ входной цепочки: %1").arg(curLex), "EVENT");

if ((topTerm=="[") && (curLex=="]")) //если верхний терминал стека '[' и текущяя лексема ']', то алгоритм завершен

{

flag=1; //алгоритм завершен

rootTreeItem->text="E";

emit setRootItem(rootTreeItem); //послать указатель на корневой узел дерева

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

}

else

{

QChar matrixValue = getMatrixValue(topTerm, getStackItemText()); //значение в ячейке матрицы предшествования

emit sendLog(tr("Отношение %1 %2 %3").arg(topTerm).arg(matrixValue).arg(curLex), "MESSAGE");

if (matrixValue==' ') //если ячейка пуста

{

setError(lexDesc.stringNumber);

emit sendLog(tr("Синтаксическая ошибка, не найдено соответствие в матрице"), "ERROR");

flag=1;

}

else if ((matrixValue=='=') || (matrixValue=='<'))

{

shift(); //сдвиг

lexemesPos++; //передвигаем считывающую головку

}

else if (matrixValue=='>')

{

reduce(); //свертка

}

else //вообще-то такого быть не должно

{

QMessageBox::critical(0, "ERROR", tr("Разработчик косяк!!"), "OK");

}

}

}

}

//сдвиг

void SynAnalyser::shift()

{

emit sendLog(tr("Сдвиг"), "END");

sItem.value=curLex;

sItem.text=getStackItemText();

sItem.node = new synTreeItem; //создаем указатель на узел дерева

sItem.node->text=sItem.value;

stack.push(sItem); //пишем текущую лексему в стек

stackSize++;

}

//свертка

void SynAnalyser::reduce()

{

emit sendLog(tr("Свертка:"), "END");

stackPos=0;

// int f=0;

curRule="";

QString curTerm; //текущий терминал (последний из добавленных в правило)

stackItem nextTerm; //терминал, который считывается в данный момент

bool isTopTerm=1; //флаг = терминал является самым верхним в стеке

QChar mtrxValue; //значение ячейки в матрице предшествования

bool ruleEnd=0; //флаг конца правила

treeItem = new synTreeItem; //создаем новый узел дерева

//для всех символов стека, начиная с вершины

while (!ruleEnd) //пока не конец правила

{

nextTerm=stack.pop(); //следующий символ вытаскиваем из верхушки стека

stackSize--;

if ((nextTerm.text=="E") || (nextTerm.text=="B")) //если нетерминал

{

curRule.prepend(nextTerm.text); //добавляем в начало текущего правила

treeItem->childItems.prepend(nextTerm.node); //добавить указатель на узел в список потомков узла

}

else //если терминал

{

if (isTopTerm) //если верхний терминал стека

{

curTerm = nextTerm.text; //делаем терминал текущим

curRule.prepend(curTerm); //добавляем терминал в начало текущего правила

treeItem->childItems.prepend(nextTerm.node); //добавить указатель на узел в список потомков узла

isTopTerm=0;

}

else //не верхний терминал

{

//если этот терминал связан с текущим символом отношением '='

if (getMatrixValue(nextTerm.text, curTerm)=='=')

{

curTerm = nextTerm.text; //делаем терминал текущим

curRule.prepend(curTerm); //добавляем терминал в начало текущего правила

treeItem->childItems.prepend(nextTerm.node); //добавить указатель на узел в список потомков узла

}

else

{

stack.push(nextTerm); //обратно добавляем неиспользованный символ в стек

stackSize++;

ruleEnd=1; //флаг конца правила

break; //выходим из цикла, правило считано

}

}

}

}

if (curRule.size()>MAXRULELENGTH)

QMessageBox::critical(0, "ERROR", tr("Превышена максимальная длина правила"), "OK");

if (!curRule.isEmpty()) //если правило не пустое, то ищем соответствующее правило

{

bool isRuleValid=0; //флаг = правило корректное

sendLog(tr("Поиск правила, соответствующего '%1'").arg(curRule), "MESSAGE");

for (int j=0; j<RULENUM; j++)

{

stackItem curRuleStruct;

if (rules[j]==curRule) //если правило совпало

//добавляем Е или В в зависимости от j

{

if (j<16) //Если правило Е (арифметическое)

{

curRuleStruct.text="E";

sendLog(tr("Соответствующее правило найдено, заменяем на 'E'"), "MESSAGE");

treeItem->text="E"; //название узла дерева

}

else //правило B (логическое)

{

curRuleStruct.text="B";

sendLog(tr("Соответствующее правило найдено, заменяем на 'B'"), "MESSAGE");

treeItem->text="B"; //название узла дерева

}

curRuleStruct.value = curRule; //значение символа

curRuleStruct.node = treeItem; //помещаем указатель на узел дерева (нетерминал)

rootTreeItem = treeItem; //на всякий случай запоминаем, как корневой узел

stack.push(curRuleStruct); //помещаем на верхушку стека нетерминал

stackSize++;

isRuleValid=1; //правило корректно

break; //выход из цикла

}

}

if (!isRuleValid) //если правило некорректно

{

QMessageBox::critical(0, "ERROR", tr("Не найдено соответствующее правило, ошибка!"), "OK");

setError(lexDesc.stringNumber); //послать сообщение о синтаксической ошибке

}

}

}

//возвращает терминал грамматики, соответствующий текущей считываемой лексеме curLex

QString SynAnalyser::getStackItemText()

{

QString type = lexDesc.type;

if (type=="CONSTANT")

return "c";

else if (type=="ID")

return "a";

else

return lexDesc.text;

}

//верхний терминал стека

QString SynAnalyser::getTopTerm()

{

QString text("");

if (stackSize<1) QMessageBox::critical(0, "ERROR", "Стек пуст!", "OK");

for (int i=stackSize-1; i>=0; i--)

{

stackItem sI;

sI = stack.at(i);

text = sI.text;

if ((text!="E") && (text!="B"))

break;

}

return text;

}

//получить номер столбца/строки терминала в матрице предшествования

int SynAnalyser::getTermNum(QString text)

{

int n;

if (text=="program")

n=0;

else if (text=="end.")

n=1;

else if (text==";")

n=2;

else if (text=="if")

n=3;

else if (text=="then")

n=4;

else if (text=="else")

n=5;

else if (text=="endif")

n=6;

else if (text=="begin")

n=7;

else if (text=="end")

n=8;

else if (text=="for")

n=9;

else if (text=="downto")

n=10;

else if (text=="do")

n=11;

else if (text=="a")

n=12;

else if (text=="c")

n=13;

else if (text==":=")

n=14;

else if (text=="or")

n=15;

else if (text=="and")

n=16;

else if (text=="not")

n=17;

else if (text=="<")

n=18;

else if (text==">")

n=19;

else if (text=="=")

n=20;

else if (text=="<>")

n=21;

else if (text=="(")

n=22;

else if (text==")")

n=23;

else if (text=="-")

n=24;

else if (text=="+")

n=25;

else if (text=="<<")

n=26;

else if (text==">>")

n=27;

else if ((text=="[") || (text=="]"))

n=28;

return n;

}

//получить значение в ячейке матрицы предшествования

QChar SynAnalyser::getMatrixValue(QString tTerm, QString fLex)

{

int i = getTermNum(tTerm); //номер строки

int j = getTermNum(fLex); //номер столбца

return matrix[i][j];

}

//сообщить об ошибке

void SynAnalyser::setError(int stringNumber)

{

QMessageBox::critical(0, "ERROR", tr("Синтаксическая ошибка в %1 строке").arg(stringNumber), "OK");

emit sendLog(tr("Синтаксическая ошибка в %1 строке").arg(stringNumber), "ERROR");

emit setRedLine(stringNumber); //выделить красным строку с ошибкой

}

void SynAnalyser::getLexemes(QVector<lexemeDescription> lexemesDesc)

{

lexemes=lexemesDesc;

sendLog(tr("Приняты лексемы от лексического анализатора"), "MESSAGE");

}

void SynAnalyser::getIdentifiers(QMap<QString, int> ids)

{

identifiers=ids;

sendLog(tr("Приняты идентификаторы от лексического анализатора"), "MESSAGE");

start(); //начать синтаксический анализ

}

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.

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