Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Курсовая работа2 / SyntaxAn
.cpp
// File: SyntaxAn.cpp
#include "StdAfx.h"
#include "SyntaxAn.h"
#include "ErrorHandler.h"
#include "PASCAL.h"
#include "Interfaces.h"
//-----------------------------------------------------------------------------
CSyntAnalyzer::CSyntAnalyzer()
{
InitTokens(PASCAL_Terms, PASCAL_RulesCount);
InitRules(PASCAL_Rules, PASCAL_RulesCount);
InitTables(PASCAL_Action, PASCAL_FCount, PASCAL_Goto, PASCAL_GCount);
}
//-----------------------------------------------------------------------------
// Достаточно дорогая операция...
// так что я бы не стал её на лету делать по несколько раз
void CSyntAnalyzer::InitTables(FInfo FV[], unsigned FVLen, GInfo GV[], unsigned GVLen)
{
unsigned i;
CSymbol sym;
for (i = 0; i < FVLen; ++i)
{
m_TableAct.At(FV[i].StackSym, FV[i].Terminal) = FV[i].Action;
}
for (i = 0; i < GVLen; ++i)
{
if (GV[i].bIsTerm)
sym = CSymbol((EnumT) GV[i].Symbol );
else sym = CSymbol((EnumNT) GV[i].Symbol );
m_TableTrans.At(GV[i].StackSym, sym) = CStackSymbol(GV[i].State);
}
}
//-----------------------------------------------------------------------------
void CSyntAnalyzer::InitRules(RuleInfo RI[], unsigned RulesCount)
{
m_vRulesInfo.assign(RI, RI + RulesCount);
}
//-----------------------------------------------------------------------------
void CSyntAnalyzer::InitTokens(ENUM_TOKENS Tokens[], unsigned Count)
{
for (unsigned i = 0; i < Count; ++i)
m_Tokens.insert(Tokens[i]);
}
//-----------------------------------------------------------------------------
int CSyntAnalyzer::f(const CSymbol &sym)
{
int res;
if (!m_TableAct.Find(m_Stack.top(), sym, res)) return ACT_ERROR;
bool bActionFound = m_TableAct.Find(m_Stack.top(), sym, res);
return res;
}
//-----------------------------------------------------------------------------
bool CSyntAnalyzer::FindToken(ENUM_TOKENS Tkn)
{
return (m_Tokens.find(Tkn) != m_Tokens.end());
}
//-----------------------------------------------------------------------------
// Если соответствующий магазинный символ не найден возвращается символ дна
CStackSymbol CSyntAnalyzer::g( const CSymbol& sym )
{
CStackSymbol res(STACK_BOTTOM);
m_TableTrans.Find(m_Stack.top(), sym, res);
return res;
}
//-----------------------------------------------------------------------------
// Мегаалгоритм, описанный в методе про восходящие методы, стр. 51
bool CSyntAnalyzer::Analyze(CTokenStream::iterator it_token, CTokenStream::iterator it_end)
{
ENUM_TOKENS CurToken;
CStackSymbol StSym( STACK_BOTTOM );
// предварительно нужно занести в стэк специальный символ - дно магазина !!!
m_Stack.push( StSym );
// Пока всё не сделаем домой не пойдём :)
while (true)
{
CurToken = (ENUM_TOKENS)(*it_token);
CSymbol Sym = CSymbol(CurToken);
int action = f( Sym );
assert(action >= -3);
switch( action )
{
case ACT_OK: return true;
case ACT_ERROR:
// тут должна быть некоторая обработка ошибок
g_ErrorHandler.Error(CError(ERR_SYNTAX_ERROR, it_token->Line()));
return false;
break;
case ACT_TRANSFER: // ПЕРЕНОС ---------
if (!m_TableTrans.Find(m_Stack.top(), Sym, StSym))
{
// ОШИБКА, тоже надо как-то обработать
g_ErrorHandler.Error(CError(ERR_SYNTAX_ERROR, it_token->Line()));
return false;
}
// Инициализируем атрибуты
StSym.Attributes().pToken = it_token;
m_Stack.push(StSym);
it_token++;
break;
default: // СВЁРТКА -----------------
// Если мы попали сюда, значение action должно быть >= 0
assert(action >= 0);
// Выполняем вычисление атрибутов и прочее и прочее...
SAttrSet AttrSet;
Operation(action, AttrSet);
// неким образом делаем свёртку по правилу с номером action
// сначала удаляем из стека нужное число символов
for (int i = 0; i < m_vRulesInfo[action].Length; ++i)
m_Stack.pop();
// Определяем новый символ T"=g(A)
StSym = g(m_vRulesInfo[action].LeftSide);
// Копируем аттрибуты
StSym.Attributes() = AttrSet;
// Пихаем в стек
m_Stack.push( StSym );
break;
}
}
return true;
}
//-----------------------------------------------------------------------------
Соседние файлы в папке Курсовая работа2