Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Курсовая работа2 / SemProc
.cpp
// File: SemProc.cpp
// Purpose: Реализация семантических процедур синт. анализа
//*****************************************************************************
#include "StdAfx.h"
#include "Interfaces.h"
#include "CodeGen.h"
#include "ErrorHandler.h"
#include "PASCAL.h"
#include "NameTables.h"
//-----------------------------------------------------------------------------
// Метод выполняет семантические процедуры при свертке по правилу RuleNum
// LeftAttrSet - набор атрибутов для нетерминала из левой части
void CCodeGen::Operation(int RuleNum, SAttrSet &LeftAttrSet)
{
TRACE("Свертка по правилу %d\n", RuleNum);
g_pOutput->Printf("Свертка по правилу %d\r\n", RuleNum);
TYPES type1 = TYPE_UNDEFINED, type2 = TYPE_UNDEFINED;
unsigned i = 0;
std::string sOp1, sOp2, sRes, sTemp;
switch( RuleNum )
{
//-------------------------------
// Cвертка простого типа
//-------------------------------
case _Type__TKN_BOOLEAN_ : LeftAttrSet.SType.T = TYPE_BOOLEAN; break;
case _Type__TKN_CHAR_ : LeftAttrSet.SType.T = TYPE_CHAR; break;
case _Type__TKN_INTEGER_ : LeftAttrSet.SType.T = TYPE_INTEGER; break;
case _Type__TKN_REAL_ : LeftAttrSet.SType.T = TYPE_REAL; break;
case _Type__TKN_STACK_ : LeftAttrSet.SType.T = TYPE_STACK; break;
case _Type__TKN_STRING_ : LeftAttrSet.SType.T = TYPE_STRING; break;
//-------------------------------
// Свертка объявления переменной
//-------------------------------
case _SingleVarDec__TKN_ID_TKN_COLON_Type_TKN_SEMICOLON_:
{
if (IsIdDeclared(m_Stack[3].Attributes()))
ErrorIdRedefinition(m_Stack[3].Attributes());
type1 = m_Stack[1].Attributes().SType.T;
i = m_Stack[3].Attributes().pToken->Index();
// Создаем новую переменную
sTemp = NewName(VarInfo(type1, false, i, false));
g_TableMgr.IDInternalName(i) = sTemp;
g_TableMgr.IDType(i) = type1;
}
break;
//-------------------------------
// Свертка объявления константы
//-------------------------------
case _SingleConstDec__TKN_ID_TKN_REL_EQUAL_Expression_TKN_SEMICOLON_ :
if (IsIdDeclared(m_Stack[3].Attributes()))
ErrorIdRedefinition(m_Stack[3].Attributes());
if (!m_Stack[1].Attributes().SExpr.bConst)
{
CError err(ERR_NONCONST_EXPR, m_Stack[2].Attributes().pToken->Line());
g_ErrorHandler.Error(err);
}
type1 = m_Stack[1].Attributes().SType.T;
i = m_Stack[3].Attributes().pToken->Index();
g_TableMgr.IDType(i) = type1;
sTemp = NewName(VarInfo(type1, false, i, false));
strcpy(m_Stack[3].Attributes().SExpr.name, sTemp.c_str());
g_TableMgr.IDInternalName(i) = sTemp;
// Присваиваем значение константе
PerformAssignment(m_Stack[3].Attributes(), m_Stack[1].Attributes());
// А теперь устанавливаем флаг константности
g_TableMgr.IDConst(i) = true;
break;
//-------------------------------
// Свертка к атому выражения
//-------------------------------
case _ExprAtom__TKN_ID_ :
if (!IsIdDeclared(m_Stack[0].Attributes())) // объявлен ли идентификатор?
ErrorIdUndeclared(m_Stack[0].Attributes());
i = m_Stack[0].Attributes().pToken->Index();
LeftAttrSet.SExpr.type = g_TableMgr.IDType(i);
// Находим имя идентификатора
strcpy(LeftAttrSet.SExpr.name, g_TableMgr.IDInternalName(i).c_str());
LeftAttrSet.SExpr.bConst = g_TableMgr.IDConst(i);
break;
case _ExprAtom__TKN_LITER_CHAR_ :
LeftAttrSet = ProcessLiter(TYPE_CHAR, m_Stack[0].Attributes().pToken->Index());
LeftAttrSet.SExpr.bConst = true;
break;
case _ExprAtom__TKN_LITER_INT_ :
LeftAttrSet = ProcessLiter(TYPE_INTEGER, m_Stack[0].Attributes().pToken->Index());
LeftAttrSet.SExpr.bConst = true;
break;
case _ExprAtom__TKN_LITER_REAL_ :
LeftAttrSet = ProcessLiter(TYPE_REAL, m_Stack[0].Attributes().pToken->Index());
LeftAttrSet.SExpr.bConst = true;
break;
case _ExprAtom__TKN_LITER_STRING_ :
LeftAttrSet = ProcessLiter(TYPE_STRING, m_Stack[0].Attributes().pToken->Index());
LeftAttrSet.SExpr.bConst = true;
break;
case _ExprAtom__TKN_TRUE_ :
case _ExprAtom__TKN_FALSE_ :
LeftAttrSet = ProcessLiter(TYPE_BOOLEAN, m_Stack[0].Attributes().pToken->Index());
LeftAttrSet.SExpr.bConst = true;
break;
case _ExprAtom__Function_ :
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprMultiplier
//-------------------------------
case _ExprMultiplier__TKN_BRACKET_OPEN_Expression_TKN_BRACKET_CLOSE_ :
LeftAttrSet = m_Stack[1].Attributes();
break;
case _ExprMultiplier__TKN_NOT_ExprMultiplier_ :
sOp1 = m_Stack[0].Attributes().SExpr.name;
sRes = NewNameTemp(VarInfo(TYPE_BOOLEAN, false, 0, true));
AddTet(TET_OP_NOT, sOp1, "", sRes);
LeftAttrSet.SExpr.type = TYPE_BOOLEAN;
strcpy(LeftAttrSet.SExpr.name, sRes.c_str());
LeftAttrSet.SExpr.bConst = m_Stack[0].Attributes().SExpr.bConst;
break;
case _ExprMultiplier__TKN_PLUS_ExprMultiplier_ :
i = m_Stack[1].Attributes().pToken->Index();
// Если унарный минус
if (g_TableMgr.GetOperation(i) == VAL_PLUS_M)
{
sOp1 = m_Stack[0].Attributes().SExpr.name;
type1 = m_Stack[0].Attributes().SExpr.type;
sRes = NewNameTemp(VarInfo(type1, false, 0, true));
if (TYPE_INTEGER == type1)
AddTet(TET_OP_UMINUS, sOp1, "", sRes);
else
AddTet(TET_OP_UMINUS_F, sOp1, "", sRes);
LeftAttrSet.SExpr.type = type1;
strcpy(LeftAttrSet.SExpr.name, sRes.c_str());
LeftAttrSet.SExpr.bConst = m_Stack[0].Attributes().SExpr.bConst;
}
else // Унарный плюс просто инорируем
LeftAttrSet = m_Stack[0].Attributes();
break;
case _ExprMultiplier__ExprAtom_ :
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprConstituent
//-------------------------------
case _ExprConstituent__ExprConstituent_TKN_MULT_ExprMultiplier_:
LeftAttrSet = PerformArithmOperBin(m_Stack[2].Attributes(), m_Stack[0].Attributes());
break;
case _ExprConstituent__ExprMultiplier_:
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprRelator
//-------------------------------
case _ExprRelator__ExprRelator_TKN_PLUS_ExprConstituent_ :
// Если знак плюс и один из операндов - строка, то пробуем выполнить конкатенацию
if ( (g_TableMgr.GetOperation(m_Stack[1].Attributes().pToken->Index()) == VAL_PLUS_P) &&
( (TYPE_STRING == m_Stack[2].Attributes().SExpr.type) ||
(TYPE_STRING == m_Stack[0].Attributes().SExpr.type)
)
)
LeftAttrSet = PerformStrConcat(m_Stack[2].Attributes(), m_Stack[0].Attributes());
else
LeftAttrSet = PerformArithmOperBin(m_Stack[2].Attributes(), m_Stack[0].Attributes());
break;
case _ExprRelator__ExprConstituent_ :
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprConjunctor
//-------------------------------
case _ExprConjunctor__ExprConjunctor_ExprRelation_ExprRelator_ :
LeftAttrSet = PerformComparisonArithm(m_Stack[2].Attributes(), m_Stack[0].Attributes());
break;
case _ExprConjunctor__ExprRelator_ :
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprDisjunctor
//-------------------------------
case _ExprDisjunctor__ExprDisjunctor_TKN_AND_ExprConjunctor_ :
LeftAttrSet = PerformBoolOperBin(TKN_AND, m_Stack[2].Attributes(), m_Stack[0].Attributes());
break;
case _ExprDisjunctor__ExprConjunctor_ :
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprDisjunctor
//-------------------------------
case _Expression__Expression_TKN_OR_ExprDisjunctor_ :
LeftAttrSet = PerformBoolOperBin(TKN_OR, m_Stack[2].Attributes(), m_Stack[0].Attributes());
break;
case _Expression__ExprDisjunctor_ :
LeftAttrSet = m_Stack[0].Attributes();
break;
//-------------------------------
// Свертки к ExprRelation
//-------------------------------
case _ExprRelation__TKN_REL_EQUAL_:
// Знак равенства
LeftAttrSet.Operation = VAL_REL_E;
break;
case _ExprRelation__TKN_REL_NOT_EQUAL_ :
i = m_Stack[0].Attributes().pToken->Index();
LeftAttrSet.Operation = g_TableMgr.GetOperation(i);
break;
//-------------------------------
// Свертка к Assignment
//-------------------------------
case _Assignment__TKN_ID_TKN_ASSIGN_Expression_ :
PerformAssignment(m_Stack[2].Attributes(), m_Stack[0].Attributes());
break;
//-------------------------------
// Свертки условного оператора
//-------------------------------
case _PartIf__TKN_IF_Expression_:
if (TYPE_BOOLEAN != m_Stack[0].Attributes().SExpr.type)
{
CError err(ERR_TYPE_MISMATCH, m_Stack[1].Attributes().pToken->Line());
g_ErrorHandler.Error(err);
}
sOp1 = m_Stack[0].Attributes().SExpr.name;
sOp2 = NewLabel();
AddTet(TET_OP_GOTO_ZERO, sOp1, sOp2, "");
strcpy(LeftAttrSet.label, sOp2.c_str());
break;
case _StatementUnmatched__PartIf_UnmatchedThen_ :
sOp1 = m_Stack[1].Attributes().label;
AddTet(TET_OP_DEF_LABEL, sOp1, "", "");
break;
case _StatementUnmatched__PartIfMatched_UnmatchedElse_ :
sOp1 = m_Stack[1].Attributes().label;
AddTet(TET_OP_DEF_LABEL, sOp1, "", "");
break;
case _PartIfMatched__PartIf_MatchedThen_ :
// прыжок за еlse
sOp1 = NewLabel();
AddTet(TET_OP_GOTO, sOp1, "", "");
strcpy(LeftAttrSet.label, sOp1.c_str());
// Тут будет метка для else
sOp1 = m_Stack[1].Attributes().label;
AddTet(TET_OP_DEF_LABEL, sOp1, "", "");
break;
case _StatementMatched__PartIfMatched_MatchedElse_ :
sOp1 = m_Stack[1].Attributes().label;
AddTet(TET_OP_DEF_LABEL, sOp1, "", "");
break;
//-------------------------------
// Свертки цикла FOR
//-------------------------------
case _ForInit__TKN_FOR_TKN_ID_TKN_ASSIGN_Expression_TKN_TO_Expression_TKN_DO_ :
#pragma REMINDER("В цикле FOR сейчас может использоваться только INTEGER ")
if (!IsIdDeclared(m_Stack[5].Attributes()))
ErrorIdUndeclared(m_Stack[5].Attributes());
i = m_Stack[5].Attributes().pToken->Index();
if ((m_Stack[3].Attributes().SExpr.type != TYPE_INTEGER) ||
(m_Stack[1].Attributes().SExpr.type != TYPE_INTEGER) ||
(g_TableMgr.IDType(i) != TYPE_INTEGER)
)
{
CError err(ERR_TYPE_MISMATCH, m_Stack[4].Attributes().pToken->Line());
g_ErrorHandler.Error(err);
}
sOp1 = m_Stack[3].Attributes().SExpr.name;
sRes = g_TableMgr.IDInternalName(i);
AddTet(TET_OP_ASSIGN_INT, sOp1, "", sRes); // Присваиваем начальное значение
strcpy(LeftAttrSet.For.VarName, sRes.c_str()); // сохраняем имя переменной
// Сохраняем в атрибуте имя переменной с верхней границей
strcpy(LeftAttrSet.For.LastName, m_Stack[1].Attributes().SExpr.name);
sOp1 = NewLabel(); // метка проверки условия цикла (после тела)
AddTet(TET_OP_GOTO, sOp1, "", "");
strcpy(LeftAttrSet.For.LabEnd, sOp1.c_str());
sOp1 = NewLabel(); // метка начала цикла
AddTet(TET_OP_DEF_LABEL, sOp1, "", "");
strcpy(LeftAttrSet.For.LabBegin, sOp1.c_str());
break;
case _StatementMatched__ForInit_StatementMatched_ :
case _StatementUnmatched__ForInit_StatementUnmatched_ :
sOp1 = m_Stack[1].Attributes().For.VarName;
sOp2 = m_Stack[1].Attributes().For.LastName;
// Инкрементируем переменную цикла
AddTet(TET_OP_INC_INT, sOp1, "", "");
// Пишем метку конца цикла
AddTet(TET_OP_DEF_LABEL, m_Stack[1].Attributes().For.LabEnd, "", "");
// Вычисляем TempVar := (i > max)
sRes = NewNameTemp(VarInfo(TYPE_BOOLEAN, false, 0, true));
AddTet(TET_OP_REL_G, sOp1, sOp2, sRes);
// Если (TempVar = false) выполняем ещё одну итерацию
sOp1 = m_Stack[1].Attributes().For.LabBegin;
AddTet(TET_OP_GOTO_ZERO, sRes, sOp1, "");
break;
//-------------------------------
// Свертки цикла While
//-------------------------------
case _WhileKeyword__TKN_WHILE_ :
// Эта свертка введена для того, чтобы метка начала была объявлена
// до вычисления выражения. Тогда выражение будет вычисляться на каждой итерации
strcpy(LeftAttrSet.While.LabBegin, NewLabel().c_str());
strcpy(LeftAttrSet.While.LabEnd, NewLabel().c_str());
// Объявляем метку начала цикла
AddTet(TET_OP_DEF_LABEL, LeftAttrSet.While.LabBegin, "", "");
break;
case _WhileInit__WhileKeyword_Expression_TKN_DO_:
if (TYPE_BOOLEAN != m_Stack[1].Attributes().SExpr.type)
{
CError err(ERR_TYPE_MISMATCH, m_Stack[0].Attributes().pToken->Line());
g_ErrorHandler.Error(err);
}
// Проверяем условие, если неверно, прыгаем в конец
AddTet(TET_OP_GOTO_ZERO, m_Stack[1].Attributes().SExpr.name, m_Stack[2].Attributes().While.LabEnd, "");
LeftAttrSet = m_Stack[2].Attributes();
break;
case _StatementMatched__WhileInit_StatementMatched_ :
case _StatementUnmatched__WhileInit_StatementUnmatched_ :
// Прыгаем в начало для проверки условия
AddTet(TET_OP_GOTO, m_Stack[1].Attributes().While.LabBegin, "", "");
AddTet(TET_OP_DEF_LABEL, m_Stack[1].Attributes().While.LabEnd, "", "");
break;
//-------------------------------
// Свертки write и read
//-------------------------------
case _StatementIO__TKN_READ_TKN_BRACKET_OPEN_TKN_ID_TKN_BRACKET_CLOSE_:
{
if (!IsIdDeclared(m_Stack[1].Attributes()))
ErrorIdUndeclared(m_Stack[1].Attributes());
i = m_Stack[1].Attributes().pToken->Index();
if (g_TableMgr.IDConst(i))
{
CError err(ERR_CONST_ASSIGN, m_Stack[1].Attributes().pToken->Line(), g_TableMgr.IDLexem(i));
g_ErrorHandler.Error(err);
}
TET_OPERATION tet_op;
switch (g_TableMgr.IDType(i))
{
case TYPE_INTEGER: tet_op = TET_OP_READ_INT; break;
case TYPE_REAL: tet_op = TET_OP_READ_REAL; break;
case TYPE_CHAR: tet_op = TET_OP_READ_CHAR; break;
case TYPE_STRING: tet_op = TET_OP_READ_STR; break;
default:
assert(false);
ErrorTypeUnsupported(m_Stack[1].Attributes().pToken->Line());
}
AddTet(tet_op, "", "", g_TableMgr.IDInternalName(i));
}
break;
case _StatementIO__TKN_WRITE_TKN_BRACKET_OPEN_Expression_TKN_BRACKET_CLOSE_:
{
TET_OPERATION tet_op;
switch (m_Stack[1].Attributes().SExpr.type)
{
case TYPE_INTEGER: tet_op = TET_OP_WRITE_INT; break;
case TYPE_REAL: tet_op = TET_OP_WRITE_REAL; break;
case TYPE_CHAR: tet_op = TET_OP_WRITE_CHAR; break;
case TYPE_STRING: tet_op = TET_OP_WRITE_STR; break;
default:
assert(false);
ErrorTypeUnsupported(m_Stack[3].Attributes().pToken->Line());
}
sOp1 = m_Stack[1].Attributes().SExpr.name;
AddTet(tet_op, sOp1, "", "");
}
break;
case _StatementIO__TKN_WRITELN_ :
AddTet(TET_OP_WRITELN, "", "", "");
break;
//-------------------------------
// Свертки стековых операций
//-------------------------------
case _Procedure__TKN_PUSH_TKN_BRACKET_OPEN_TKN_ID_TKN_COMMA_Expression_TKN_BRACKET_CLOSE_ :
if (TYPE_CHAR != m_Stack[1].Attributes().SExpr.type)
ErrorTypeUnsupported(m_Stack[2].Attributes().pToken->Line());
if (!IsIdDeclared(m_Stack[3].Attributes()))
ErrorIdUndeclared(m_Stack[3].Attributes());
type1 = g_TableMgr.IDType(m_Stack[3].Attributes().pToken->Index());
if (TYPE_STACK != type1)
ErrorTypeUnsupported(m_Stack[3].Attributes().pToken->Line());
sOp1 = g_TableMgr.IDInternalName(m_Stack[3].Attributes().pToken->Index());
AddTet(TET_OP_STACK_PUSH, sOp1, m_Stack[1].Attributes().SExpr.name, "");
break;
case _Function__TKN_TOP_TKN_BRACKET_OPEN_TKN_ID_TKN_BRACKET_CLOSE_ :
if (!IsIdDeclared(m_Stack[1].Attributes()))
ErrorIdUndeclared(m_Stack[1].Attributes());
type1 = g_TableMgr.IDType(m_Stack[1].Attributes().pToken->Index());
if (TYPE_STACK != type1)
ErrorTypeUnsupported(m_Stack[1].Attributes().pToken->Line());
LeftAttrSet.SExpr.type = TYPE_CHAR;
strcpy(LeftAttrSet.SExpr.name, NewNameTemp(VarInfo(TYPE_CHAR, false, 0, true)).c_str());
LeftAttrSet.SExpr.bConst = false;
sOp1 = g_TableMgr.IDInternalName(m_Stack[1].Attributes().pToken->Index());
AddTet(TET_OP_STACK_TOP, sOp1, "", LeftAttrSet.SExpr.name);
break;
case _Procedure__TKN_POP_TKN_BRACKET_OPEN_TKN_ID_TKN_BRACKET_CLOSE_ :
if (!IsIdDeclared(m_Stack[1].Attributes()))
ErrorIdUndeclared(m_Stack[1].Attributes());
type1 = g_TableMgr.IDType(m_Stack[1].Attributes().pToken->Index());
if (TYPE_STACK != type1)
ErrorTypeUnsupported(m_Stack[1].Attributes().pToken->Line());
sOp1 = g_TableMgr.IDInternalName(m_Stack[1].Attributes().pToken->Index());
AddTet(TET_OP_STACK_POP, sOp1, "", "");
break;
}
}
Соседние файлы в папке Курсовая работа2