?? pascalcompiler.cpp
字號:
// PascalSintAnalyzer.cpp: implementation of the CPascalCompiler class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zscpascal.h"
#include "PascalCompiler.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPascalCompiler::CPascalCompiler(CString str):
CPascalLexAnalyzer(str)
{
m_nICod = 0;
m_nIdeplas = 0;
m_nVAdrel = 0;
m_nVDimv = 0;
m_nVNivel = 0;
m_nVNrPar = 0;
}
CPascalCompiler::~CPascalCompiler()
{
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::ProgramSursa()
{
IncreaseLevel();
m_nVAdrel = 0;
if (NextToken() != TT_KW_PROGRAM)
throw error(SET_EXPECTED,CString("\"program\""));
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
// proceseaza nume program
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
Bloc();
if (NextToken() != '.')
throw error(SET_EXPECTED, CString("."));
DecreaseLevel();
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::Bloc()
{
int temp = m_nVAdrel;
m_nVAdrel = 0;
int val;
while (1)
{
if ((val = NextToken()) == TT_KW_CONST)
ListaDeclConst();
else
if (val == TT_KW_VAR)
ListaDeclVar();
else
if (val == TT_KW_PROCEDURE)
{
IncreaseLevel();
ParamList lp;
CString nume;
AntetProc(lp,nume);
Bloc();
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
Symbol simb;
simb.m_sName = nume;
simb.m_nClass = CT_PROCEDURE;
simb.m_nNivel = m_nVNivel;
simb.m_nAdrStart = -1;
// INCDOM
//simb.m_nIncDom =
simb.m_ListaPar .AddTail(&lp);
simb.m_nNrPar = lp.GetCount ();
// Dimensiunea variabileleor locale
//simb.m_nDimVar
DecreaseLevel();
InsertSymbol(simb);
}
else
if (val == TT_KW_FUNCTION)
{
IncreaseLevel();
int type;
ParamList lp;
CString nume;
AntetFunc(lp,type,nume);
Bloc();
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
Symbol simb;
simb.m_sName = nume;
simb.m_nClass = CT_FUNCTION;
simb.m_nNivel = m_nVNivel;
simb.m_nAdrStart = -1;
simb.m_nType = type;
// INCDOM
//simb.m_nIncDom =
simb.m_ListaPar .AddTail(&lp);
simb.m_nNrPar = lp.GetCount ();
// Dimensiunea variabileleor locale
//simb.m_nDimVar =
DecreaseLevel();
InsertSymbol(simb);
}
else
{
PushBack();
InstrCompusa();
break;
}
}
m_nVAdrel = temp;
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::ListaDeclConst()
{
while (1)
{
DeclConst();
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
if (NextToken() != TT_WORD)
{
PushBack();
break;
}
PushBack();
}
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::DeclConst()
{
Symbol simb; // simbolul asociat constantei
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
simb.m_sName = GetStrValue();
if (NextToken() != '=')
throw error(SET_EXPECTED, CString("="));
ExpStat ct;
ExprStatica(ct);
simb.m_nClass = CT_CONST;
simb.m_nNivel = m_nVNivel;
simb.m_Val = m_ListaConstante.AddHead (ct);
InsertSymbol (simb);
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::ListaDeclVar()
{
while (1)
{
DeclVar();
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
if (NextToken() != TT_WORD)
{
PushBack();
break;
}
PushBack();
}
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::AntetProc(ParamList &listaParam, CString &nume)
{
if (NextToken()!= TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
nume = GetStrValue();
if (NextToken()== ';')
return;
PushBack();
Parametri(listaParam);
if (NextToken()!= ';')
throw error(SET_EXPECTED, CString(";"));
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::AntetFunc(ParamList &listaParam, int &type, CString &nume)
{
if (NextToken()!= TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));;
nume = GetStrValue();
if (NextToken()!= ':')
{
PushBack();
Parametri(listaParam);
if (NextToken()!= ':')
throw error(SET_EXPECTED, CString(":"));
}
TypeInfo info;
TipSimplu(info);
if (NextToken()!= ';')
throw error(SET_EXPECTED, CString(";"));
type = info.m_nType ;
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::Tip(TypeInfo &info)
{
int val = NextToken();
if (val == TT_KW_INTEGER
|| val == TT_KW_REAL
|| val == TT_KW_CHAR)
{
PushBack();
info.m_nClass = CT_VAR_SIMP;
TipSimplu(info);
}
if (val == TT_KW_ARRAY)
{
PushBack();
info.m_nClass = CT_VAR_ARRAY;
TipTablou(info);
}
if (val == TT_KW_RECORD)
{
PushBack();
info.m_nClass = CT_VAR_RECORD;
TipRecord(info);
}
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::TipSimplu(TypeInfo& info)
{
int val = NextToken();
if (val == TT_KW_INTEGER)
{
info.m_nType = ST_INTEGER;
info.m_nSize = SC_INT;
}
else
if (val == TT_KW_REAL)
{
info.m_nType = ST_REAL;
info.m_nSize = SC_REAL;
}
else
if (val == TT_KW_CHAR)
{
info.m_nType = ST_CHAR;
info.m_nSize = SC_CHAR;
}
else
throw error(SET_EXPECTED, CString("Basic Type"));;
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::Parametri(ParamList &listaParam)
{
if (NextToken()!= '(')
throw error(SET_EXPECTED, CString("("));;
while (1)
{
DeclParam(listaParam);
if (NextToken()!= ';')
{
PushBack();
break;
}
}
if (NextToken()!= ')')
throw error(SET_EXPECTED, CString(")"));;
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::DeclParam(ParamList &listaParam)
{
int transmisie = LV_VALUE;
StringList list;
if (NextToken() == TT_KW_VAR)
{
transmisie = LV_ADDRESS;
NextToken();
}
PushBack();
while (1)
{
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));;
list.AddTail(GetStrValue());
if (NextToken()!=',')
{
PushBack();
break;
}
}
if (NextToken() != ':')
throw error(SET_EXPECTED, CString(":"));
TypeInfo info;
TipSimplu(info);
POSITION pos = list.GetHeadPosition();
while (pos != NULL)
{
CString numepar = list.GetNext(pos);
Symbol simb;
simb.m_sName = numepar;
if (transmisie == LV_VALUE)
simb.m_nClass = CT_PARAM_VAL;
else
simb.m_nClass = CT_PARAM_ADR;
simb.m_nType = info.m_nType ;
InsertSymbol(simb);
Param par;
par.m_nTransmisie =transmisie;
par.m_nType = info.m_nType ;
listaParam.AddTail (par);
}
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::InstrCompusa()
{
if (NextToken()!= TT_KW_BEGIN)
throw error(SET_EXPECTED, CString("begin"));;
while (1)
{
Instr();
if (NextToken()==TT_KW_END)
{
PushBack();
break;
}
PushBack();
if (NextToken()==';')
if (NextToken()==TT_KW_END)
{
PushBack();
break;
}
else PushBack();
else throw error(SET_EXPECTED, CString("end or ;"));
}
if (NextToken()!=TT_KW_END)
throw error(SET_EXPECTED, CString("end"));
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::ExprStatica(ExpStat &ct)
{
ExpStat cres;
double dResult = 0;
CString sResult = _T("");
int nResult = 0;
int type = 0;
int c = '+';
while (1)
{
TermenStatic(cres);
switch (type) // tipul termenului precedent
{
case ET_REAL:
if (cres.m_nType !=ET_REAL)
throw error(SET_INVALID_OP_TYPES,CString("real type expected"));
switch (c)
{
case '+':
dResult += cres.m_dVal;
break;
case '-':
dResult -= cres.m_dVal;
break;
}
case ET_INTEGER:
if (cres.m_nType !=ET_INTEGER)
throw error(SET_INVALID_OP_TYPES,CString("integer type expected"));
switch (c)
{
case '+':
nResult += cres.m_nVal;
break;
case '-':
nResult -= cres.m_nVal;
break;
}
break;
case ET_STRING:
if (cres.m_nType !=type)
throw error(SET_INVALID_OP_TYPES,CString("String type expected"));
switch (c)
{
case '+':
sResult += cres.m_sVal;
break;
case '-':
throw error(SET_INVALID_OP,CString("Can'tsubstract two strings"));
break;
}
break;
default:
sResult = cres.m_sVal;
dResult = cres.m_dVal;
nResult = cres.m_nVal;
type = cres.m_nType;
}
int val = NextToken();
if (val!='+' && val != '-')
{
PushBack();
break;
}
c = val;
}
ct.m_dVal = dResult;
ct.m_sVal = sResult;
ct.m_nVal = nResult;
ct.m_nType = type;
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::DeclVar()
{
TypeInfo info;
while (1)
{
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
info.m_VarList .AddTail (GetStrValue()); // insert var name to the list
if (NextToken()!=',')
{
PushBack();
break;
}
}
if (NextToken()!=':')
throw error(SET_EXPECTED, CString(":"));
Tip(info);
// insert tyhe symbols in the symbol table
POSITION pos = info.m_VarList .GetHeadPosition ();
while (pos != NULL)
{
CString name = info.m_VarList .GetNext(pos);
Symbol simb;
simb.m_nNivel = m_nVNivel;
simb.m_nClass = info.m_nClass ;
simb.m_nType = info.m_nType ;
simb.m_nIndMin = info.m_nIndMin ;
simb.m_nIndMax = info.m_nIndMax ;
simb.m_sName = name;
simb.m_nAdrel = info.m_nSize ;
m_nVAdrel += info.m_nSize ;
InsertSymbol(simb);
}
// hey am I cool or what?
}
/*
***header
***name
***memberof
***history
1.0.0 ; 1999.1.7 ; FZ ; Creation
***description
***notes
***uses
***var_in
***var_out
***err_out
***flags
***specifications
***documents
*/
void CPascalCompiler::TipTablou(TypeInfo& info)
{
if (NextToken() != TT_KW_ARRAY)
throw error(SET_EXPECTED, CString("array"));
if (NextToken() != '[')
throw error(SET_EXPECTED, CString("["));
if (NextToken() != TT_INTEGER) // trebuie modificat pentru numar zecimal
throw error(SET_EXPECTED, CString("number"));
info.m_nIndMin = (int) GetNumValue();
if (NextToken() != '.')
throw error(SET_EXPECTED, CString(".."));
if (NextToken() != '.')
throw error(SET_EXPECTED, CString(".."));
if (NextToken() != TT_INTEGER) // trebuie modificat pentru numar zecimal
throw error(SET_EXPECTED, CString("number"));
info.m_nIndMax = (int) GetNumValue();
// verifica daca indicii sunt corecti (indmin<indmax)
if (info.m_nIndMin>=info.m_nIndMax)
throw error(SET_GENERAL,CString("The Ind MAX must be greater than Ind MIN"));
if (NextToken() != ']')
throw error(SET_EXPECTED, CString("]"));
if (NextToken() != TT_KW_OF)
throw error(SET_EXPECTED, CString("of"));
TipSimplu(info);
info.m_nSize *= info.m_nIndMax - info.m_nIndMin + 1;
}
/*
***header
***name
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -