Скачиваний:
11
Добавлен:
01.05.2014
Размер:
20.34 Кб
Скачать

// 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