Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
2298 lines (1889 sloc) 63 KB
// ðåàëèçàöèÿ ñèíòàêñè÷åñêîãî àíàëèçàòîðà - Parser.cpp
#pragma warning(disable: 4786)
#include <nrc.h>
using namespace NRC;
#include "Limits.h"
#include "Application.h"
#include "Object.h"
#include "Scope.h"
#include "LexicalAnalyzer.h"
#include "Class.h"
#include "Manager.h"
#include "Maker.h"
#include "MemberMaker.h"
#include "Parser.h"
#include "Body.h"
#include "Coordinator.h"
#include "Reader.h"
#include "Checker.h"
#include "ExpressionMaker.h"
#include "BodyMaker.h"
#include "Translator.h"
using namespace ParserUtils;
// ñ÷åò÷èê ïåðåïîëíåíèÿ
int OverflowController::counter = 0;
// ñ÷åò÷èê ïåðåïîëíåíèÿ äëÿ êîíñòðóêöèé
int StatementParserImpl::OverflowStackController::deep = 0;
// ïðîâåðÿåò ïî ïàêåòó, è ïîñëåäíåé ñ÷èòàííîé ëåêñåìå, âîçìîæíî
// ëè îïðåäåëåíèå êëàññà
inline static bool NeedClassParserImpl( const Lexem &lastLxm, const NodePackage *np ) ;
// ïðîâåðÿåò ïî èäåíòèôèêàòîðó è ïîñëåäíåé ñ÷èòàííîé ëåêñåìå, íåîáõîäèì
// ëè ôóíêöèè ðàçáîð òåëà
inline static bool NeedFunctionParserImpl( LexicalAnalyzer &la, const Identifier *id );
// ïðîâåðÿåò ïî ïàêåòó, è ïîñëåäíåé ñ÷èòàííîé ëåêñåìå, òðåáóåòñÿ ëè
// îïðåäåëåíèå ïåðå÷èñëåíèÿ
inline static bool NeedEnumReading( const Lexem &lastLxm, const NodePackage *np ) ;
// ñ÷èòàòü ñïèñîê èíèöèàëèçàöèè è âûïîëíèòü ïðîâåðêó
inline static ListInitComponent *ReadInitList( LexicalAnalyzer &la,
PDeclarationMaker &pdm, const Position &errPos );
// ìåòîä çàïóñêà ñèíòàêñè÷åñêîãî àíàëèçàòîðà
void Parser::Run()
{
Lexem lxm;
for( ;; )
{
lxm = lexicalAnalyzer.NextLexem();
if( lxm == EOF )
{
// âñå îáëàñòè âèäèìîñòè äîëæíû áûòü çàêðûòû
if( !GetCurrentSymbolTable().IsGlobalSymbolTable() )
theApp.Fatal( lxm.GetPos(), "íåîæèäàííûé êîíåö ôàéëà" );
break;
}
// ëèáî îáúÿâëåíèå îáëàñòè âèäèìîñòè, ëèáî îáúÿâëåíèå ñèíîíèìà ÎÂ
if( lxm == KWNAMESPACE )
{
lxm = lexicalAnalyzer.NextLexem();
// áåçèìÿííàÿ îáëàñòü âèäèìîñòè
if( lxm == '{' )
{
if( MakerUtils::MakeNamepsaceDeclRegion(NULL) )
crampControl.push_back(0);
}
// èíà÷å ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè
else
{
lexicalAnalyzer.BackLexem();
try {
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(lexicalAnalyzer,
false, true).ReadQualifiedConstruction();
Lexem nxt = lexicalAnalyzer.NextLexem() ;
// âîçìîæíî èäåò îáúÿâëåíèå ñèíîíèìà îáëàñòè âèäèìîñòè
if( nxt == '=' )
{
MakerUtils::MakeNamespaceAlias( &*nspkg, &*QualifiedConstructionReader(
lexicalAnalyzer, false, true).ReadQualifiedConstruction());
if( lexicalAnalyzer.NextLexem() != ';' )
throw lexicalAnalyzer.LastLexem();
}
else
{
if( MakerUtils::MakeNamepsaceDeclRegion(&*nspkg) )
crampControl.push_back(0);
if( nxt != '{' )
SyntaxError(nxt);
}
} catch( const Lexem &ep ) {
SyntaxError(ep);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
}
}
}
// using namespace 'name' èëè
// using 'name'
else if( lxm == KWUSING )
{
// èñïîëüçîâàíèå îáëàñòè âèäèìîñòè
if( lexicalAnalyzer.NextLexem() == KWNAMESPACE )
{
try {
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(lexicalAnalyzer,
false, true).ReadQualifiedConstruction();
MakerUtils::MakeUsingNamespace( &*nspkg );
if( lexicalAnalyzer.NextLexem() != ';' )
throw lexicalAnalyzer.LastLexem();
} catch( const Lexem &ep ) {
SyntaxError(ep);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
}
}
// èíà÷å using-äåêëàðàöèÿ
else
{
lexicalAnalyzer.BackLexem();
try {
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(
lexicalAnalyzer).ReadQualifiedConstruction();
MakerUtils::MakeUsingNotMember( &*nspkg );
if( lexicalAnalyzer.NextLexem() != ';' )
throw lexicalAnalyzer.LastLexem();
} catch( const Lexem &ep ) {
SyntaxError(ep);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
}
}
}
else if( lxm == '}' )
{
// ïðîâåðÿåì, ÷òî íàõîäèòñÿ â crampControl. Åñëè 0,
// äîñòàåì èç ñòåêà îáëàñòü âèäèìîñòè, èíà÷å çàäàåì íîâóþ
// ñïåöèôèêàöèþ ñâÿçûâàíèÿ
if( crampControl.empty() )
SyntaxError(lxm);
else if( crampControl.back() != 0 )
{
crampControl.pop_back();
linkSpec = crampControl.empty() || crampControl.back() != 1 ? LS_CPP : LS_C;
}
// èíà÷å èìåíîâàííàÿ îáëàñòü âèäèìîñòè
else
{
INTERNAL_IF( !GetCurrentSymbolTable().IsNamespaceSymbolTable() );
GetScopeSystem().DestroySymbolTable();
crampControl.pop_back();
}
}
else
{
lexicalAnalyzer.BackLexem();
DeclareParserImpl(lexicalAnalyzer).Parse();
}
}
}
// ìåòîä ðàçáîðà äåêëàðàöèé, âîçâðàùàåò ïàêåò, ïî çàãîëîâêó êîòîðãî
// ìîæíî îïðåäåëèòü ÷òî äåëàòü äàëüøå: ñîçäàâàòü ïàðñåð êëàññ,
// ñîçäàâàòü ïàðñåð ôóíêöèè, ëèáî ïðåêðàòèòü, ò.ê. äåêëàðàöèÿ ïðîàíàëèçèðîâàíà.
//  ñëó÷àå åñëè ïðåêðàòèòü, èíòåëëåêòóàëüíûé óêàçàòåëü ñàì îñâîáîäèò ïàìÿòü
void DeclareParserImpl::Parse()
{
NodePackage *tsl = NULL, *dcl = NULL;
DeclaratorReader dr(DV_GLOBAL_DECLARATION, lexicalAnalyzer);
try {
dr.ReadTypeSpecifierList();
tsl = dr.GetTypeSpecPackage().Release();
// åñëè ïîñëåäíÿÿ ñ÷èòàííàÿ ëåêñåìà '{', à ïðåäïîñëåäíÿÿ "ñòðîêà",
// çíà÷èò èìååì ñïåöèôèêàöèþ ñâÿçûâàíèÿ, è âûõîäèì
if( lexicalAnalyzer.LastLexem() == '{' && tsl->GetLastChildPackage() &&
tsl->GetLastChildPackage()->GetPackageID() == STRING )
return;
// â ýòîì ìåñòå ìîæåò áûòü îïðåäåëåíèå êëàññà, åñëè ïîñëåäíèå
// äâà ïàêåòà áûëè êëþ÷ êëàññà è PC_QUALIFIED_NAME, à ïîñëåäíÿÿ
// ñ÷èòàííàÿ ëåêñåìà - '{' èëè ':'
if( NeedClassParserImpl(lexicalAnalyzer.LastLexem(), tsl) )
{
ClassParserImpl cpi(lexicalAnalyzer, tsl, ClassMember::NOT_CLASS_MEMBER);
cpi.Parse();
// ãåíåðèðóåì îïðåäåëåíèå êëàññà, åñëè êëàññ áûë ïîñòðîåí
if( cpi.IsBuilt() )
TranslatorUtils::TranslateClass(cpi.GetClassType());
// çàâåðøàåì îïðåäåëåíèå
if( lexicalAnalyzer.NextLexem() == ';' )
{
delete tsl;
return;
}
else
lexicalAnalyzer.BackLexem();
}
// èíà÷å åñëè òðåáóåòñÿ ñ÷èòàòü ïåðå÷èñëåíèå, ñ÷èòûâàåì
else if( NeedEnumReading(lexicalAnalyzer.LastLexem(), tsl) )
{
EnumParserImpl epi(lexicalAnalyzer, tsl, ClassMember::NOT_CLASS_MEMBER);
epi.Parse();
if( lexicalAnalyzer.NextLexem() == ';' )
{
delete tsl;
return;
}
else
lexicalAnalyzer.BackLexem();
}
// èíà÷å åñëè îáúÿâëåíèå êëàññà èëè ïåðå÷èñëåíèÿ
else if( tsl->GetChildPackageCount() == 2 &&
tsl->GetChildPackage(1)->GetPackageID() == PC_QUALIFIED_NAME &&
lexicalAnalyzer.LastLexem() == ';' )
{
register int pc = tsl->GetChildPackage(0)->GetPackageID() ;
lexicalAnalyzer.NextLexem();
if( pc == KWCLASS || pc == KWSTRUCT || pc == KWUNION )
{
ClassTypeMaker ctm( tsl, ClassMember::NOT_CLASS_MEMBER );
ctm.Make();
return;
}
else if( pc == KWENUM )
{
EnumTypeMaker etm( tsl, ClassMember::NOT_CLASS_MEMBER );
etm.Make();
return;
}
}
// ñ÷èòûâàåì ñïèñîê äåêëàðàöèé
bool firstDecl = true;
for( ;; )
{
dcl = dr.ReadNextDeclarator().Release();
// â äåêëàðàöèè äîëæíî ïðèñóòñòâîâàòü èìÿ
if( dcl->FindPackage(PC_QUALIFIED_NAME) < 0 )
throw lexicalAnalyzer.LastLexem() ;
// äàëåå ñîçäàåì äåêëàðàöèþ èç ïàêåòà è ïðîâåðÿåì åå
DeclarationCoordinator dcoord(tsl, dcl);
PDeclarationMaker dmak = dcoord.Coordinate();
if( !dmak.IsNull() )
{
dmak->Make();
// äàëåå èäåò ïðîâåðêà íà òåëî ôóíêöèè, äîëæíû áûòü ñëåä. óñëîâèÿ
// 1. ýòî ïåðâàÿ äåêëàðàöèÿ
// 2. èäåíòèôèêàòîð ÿâëÿåòñÿ ôóíêöèåé
// 3. ïîñëåäíÿÿ ñ÷èòàííàÿ ëåêñåìà - '{', èëè ':', try - åñëè ôóíêöèÿ êîíñòðóêòîð
if( firstDecl )
{
if( NeedFunctionParserImpl(lexicalAnalyzer, dmak->GetIdentifier()) )
{
Function &fn = *const_cast<Function *>(
static_cast<const Function *>(dmak->GetIdentifier()) );
// åñëè ó ôóíêöèè óæå åñòü òåëî, èãíîðèðóåì åãî è âûõîäèì
if( fn.IsHaveBody() )
{
theApp.Error(lexicalAnalyzer.LastLexem().GetPos(),
"'%s' - ó ôóíêöèè óæå åñòü òåëî",
fn.GetQualifiedName().c_str());
// èãíîðèðóåì åãî
lexicalAnalyzer.BackLexem();
FunctionBodyReader(lexicalAnalyzer, true).Read();
}
else
{
lexicalAnalyzer.BackLexem();
FunctionParserImpl fnpi(lexicalAnalyzer, fn);
fnpi.Parse();
}
dcoord.RestoreScopeSystem();
return;
}
firstDecl = false;
}
}
// èíèöèàëèçàòîð îáúåêòà, çàäàåì äëÿ ãåíåðàöèè
PObjectInitializator objIator = NULL;
// ñ÷èòûâàåì èíèöèàëèçàòîð
PExpressionList initList = dr.GetInitializatorList();
if( lexicalAnalyzer.LastLexem() == '=' )
{
// åñëè ñïèñîê èíèöèàëèçàòîðîâ óæå ñ÷èòàí, òî ýòî ñèíòàêñè÷åñêàÿ
// îøèáêà
if( !initList.IsNull() )
throw lexicalAnalyzer.LastLexem();
// ïðîâåðÿåì, åñëè ñëåäóþùàÿ ëåêñåìà '{',
// çíà÷èò ñ÷èòûâàåì ñïèñîê èíèöèàëèçàöèè
else if( lexicalAnalyzer.NextLexem() == '{' )
{
objIator = BodyMakerUtils::MakeObjectInitializator(
ReadInitList(lexicalAnalyzer, dmak, lexicalAnalyzer.LastLexem().GetPos()) );
INTERNAL_IF( dmak.IsNull() );
// ãåíåðèðóåì äåêëàðàöèþ
TranslatorUtils::TranslateDeclaration(
*dynamic_cast<const TypyziedEntity *>(dmak->GetIdentifier()),
objIator, true);
// ïðåäîòâðàùàåì ïðîâåðêó èíèöèàëèçàöèè
dmak = NULL;
}
// èíà÷å ñ÷èòûâàåì îáû÷íîå âûðàæåíèå
else
{
lexicalAnalyzer.BackLexem();
ExpressionReader er( lexicalAnalyzer, NULL, true );
er.Read();
initList = new ExpressionList;
initList->push_back(er.GetResultOperand());
}
}
// èíèöèàëèçèðóåì îáúåêò ñïèñêîì çíà÷åíèé. Ñïèñîê çíà÷åíèé
// ìîæåò îòñóòñòâîâàòü, â ýòîì ñëó÷àå ïðîèñõîäèò èíèöèàëèçàöèÿ ïî óìîë÷àíèþ
if( !dmak.IsNull() && dmak->GetIdentifier() != NULL )
{
dmak->Initialize( *initList );
// ñòðîèòåëü ìîæåò âåðíóòü NULL, åñëè èäåíòèôèêàòîð íå ÿâëÿåòñÿ îáúåêòîì
objIator = BodyMakerUtils::MakeObjectInitializator(initList, *dmak);
// ãåíåðèðóåì äåêëàðàöèþ
TranslatorUtils::TranslateDeclaration(
*dynamic_cast<const TypyziedEntity *>(dmak->GetIdentifier()),
objIator, true);
}
// âîçìîæíî áûëî îáúÿâëåíèå ÷ëåíà, â ýòîì ñëó÷àå òðåáóåòñÿ
// âîññòàíîâèòü ñèñòåìó ÎÂ, ò.ê. â íåå áûëè ïîìåùåíû îáëàñòè
// âèäèìîñòè ÷ëåíà
dcoord.RestoreScopeSystem();
if( lexicalAnalyzer.LastLexem() != ';' &&
lexicalAnalyzer.LastLexem() != ',' )
throw lexicalAnalyzer.LastLexem() ;
if( lexicalAnalyzer.LastLexem() == ';' )
break;
delete dcl;
dcl = NULL;
}
} catch( Lexem &lxm ) {
SyntaxError(lxm);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
}
delete dcl;
delete tsl;
}
// ìåòîä ðàçáîðà äåêëàðàöèé. Âîçâðàùàåò true, åñëè äåêëàðàöèÿ áûëà ñ÷èòàíà,
// èíà÷å âîçâðàùàåò false
void InstructionParserImpl::Parse()
{
// ñ÷èòûâàíèå, ëèáî âûðàæåíèÿ, ëèáî äåêëàðàöèè
TypeExpressionReader ter( lexicalAnalyzer );
const NodePackage *tsl = NULL;
// èíñòðóêöèè ìîãóò âîçáóæäàòü èñêëþ÷èòåëüíûå ñèòóàöèè
try
{
ter.Read();
INTERNAL_IF( ter.GetResultPackage() == NULL );
// åñëè èìååì âûðàæåíèå, äîëæíî áûòü ';', è íà ýòîì ðàçáîð èíòñðóêöèé
// çàêàí÷èâàåòñÿ
if( ter.GetResultPackage()->IsExpressionPackage() )
{
const ExpressionPackage &epkg =
static_cast<const ExpressionPackage &>(*ter.GetResultPackage());
#if _DEBUG
// cout << ExpressionPrinter(epkg.GetExpression()).GetExpressionString() << endl;
{
const ClassType *thisCls = NULL;
if( const FunctionSymbolTable *fst = GetScopeSystem().GetFunctionSymbolTable() )
if( fst->GetParentSymbolTable().IsClassSymbolTable() )
thisCls = &static_cast<const ClassType &>(fst->GetParentSymbolTable());
ExpressionGenerator eg(epkg.GetExpression(), thisCls);
eg.Generate();
cout << eg.GetOutBuffer() << endl;
} //*/
#endif
if( lexicalAnalyzer.LastLexem() != ';' )
throw lexicalAnalyzer.LastLexem() ;
// ñòðîèì èíñòðóêöèþ è âûõîäèì
insList.push_back( BodyMakerUtils::ExpressionInstructionMaker(epkg.GetExpression(),
lexicalAnalyzer.LastLexem().GetPos()) );
delete &epkg;
return;
}
// åñëè åñòü äåêëàðàöèÿ êëàññà, ñîõðàíÿåì åãî â ñïèñêå
if( ter.GetRedClass() )
insList.push_back( BodyMakerUtils::ClassInstructionMaker(*ter.GetRedClass(),
lexicalAnalyzer.LastLexem().GetPos()) );
// èíà÷å èìååì äåêëàðàöèþ
SmartPtr<const NodePackage> rpkg =
static_cast<const NodePackage *>(ter.GetResultPackage());
// ïðîâåðÿåì, åñëè èìååì äåêëàðàöèþ òèïà, çíà÷èò ïîñëåäíÿÿ ñ÷èòàííàÿ ëåêñåìà ';'
// è íåîáõîäèìî âûéòè, äåêëàðàöèÿ óæå ïîñòðîåíèÿ
if( rpkg->GetPackageID() == PC_CLASS_DECLARATION )
return ;
// èíà÷å ïðîâåðÿåì, ñ÷èòàíà ëè äåêëàðàöèÿ
const NodePackage *tsl = static_cast<const NodePackage*>(rpkg->GetChildPackage(0));
INTERNAL_IF( rpkg->GetPackageID() != PC_DECLARATION ||
rpkg->GetChildPackageCount() != 2 );
AutoDeclarationCoordinator dcoord(tsl, (NodePackage*)rpkg->GetChildPackage(1));
PDeclarationMaker dmak = dcoord.Coordinate();
// ñòðîèì äåêëàðàöèþ
if( !dmak.IsNull() )
dmak->Make();
// èíèöèàëèçàòîð îáúåêòà, çàäàåì äëÿ ãåíåðàöèè
PObjectInitializator objIator = NULL;
// ñ÷èòûâàåì èíèöèàëèçàòîð
PExpressionList initList = ter.GetInitializatorList();
if( lexicalAnalyzer.LastLexem() == '=' )
{
// åñëè ñïèñîê èíèöèàëèçàòîðîâ óæå ñ÷èòàí, òî ýòî ñèíòàêñè÷åñêàÿ
// îøèáêà
if( !initList.IsNull() )
throw lexicalAnalyzer.LastLexem();
// ïðîâåðÿåì, åñëè ñëåäóþùàÿ ëåêñåìà '{',
// çíà÷èò ñ÷èòûâàåì ñïèñîê èíèöèàëèçàöèè
else if( lexicalAnalyzer.NextLexem() == '{' )
{
objIator = BodyMakerUtils::MakeObjectInitializator(
ReadInitList(lexicalAnalyzer, dmak, lexicalAnalyzer.LastLexem().GetPos()) );
// ïîñëå òîãî, êàê èíèöèàëèçàòîð è èäåíòèôèêàòîð èçâåñòíû, ñòðîèì äåêëàðàöèþ
insList.push_back( BodyMakerUtils::DeclarationInstructionMaker(
*dynamic_cast<const TypyziedEntity *>(dmak->GetIdentifier()), objIator,
lexicalAnalyzer.LastLexem().GetPos() ) );
// ïðåäîòâðàùàåì ïðîâåðêó èíèöèàëèçàöèè
dmak = NULL;
}
// èíà÷å ñ÷èòûâàåì îáû÷íîå âûðàæåíèå
else
{
lexicalAnalyzer.BackLexem();
ExpressionReader er( lexicalAnalyzer, NULL, true );
er.Read();
initList = new ExpressionList;
initList->push_back(er.GetResultOperand());
}
}
// èíèöèàëèçèðóåì îáúåêò ñïèñêîì çíà÷åíèé. Ñïèñîê çíà÷åíèé
// ìîæåò îòñóòñòâîâàòü, â ýòîì ñëó÷àå ïðîèñõîäèò èíèöèàëèçàöèÿ ïî óìîë÷àíèþ
if( !dmak.IsNull() && dmak->GetIdentifier() != NULL )
{
dmak->Initialize( *initList ),
// ñòðîèòåëü ìîæåò âåðíóòü NULL, åñëè èäåíòèôèêàòîð íå ÿâëÿåòñÿ îáúåêòîì
objIator = BodyMakerUtils::MakeObjectInitializator(initList, *dmak);
// ïîñëå òîãî, êàê èíèöèàëèçàòîð è èäåíòèôèêàòîð èçâåñòíû, ñòðîèì äåêëàðàöèþ
insList.push_back( BodyMakerUtils::DeclarationInstructionMaker(
*dynamic_cast<const TypyziedEntity *>(dmak->GetIdentifier()), objIator,
lexicalAnalyzer.LastLexem().GetPos() ) );
}
if( lexicalAnalyzer.LastLexem() == ';' )
;
// èíà÷å, åñëè íå ',', âûâîäèì ñèíòàêñè÷åñêóþ îøèáêó
else if( lexicalAnalyzer.LastLexem() != ',' )
throw lexicalAnalyzer.LastLexem() ;
// èíà÷å ñ÷èòûâàåì ñïèñîê äåêëàðàöèé
else
for( ;; )
{
DeclaratorReader dr(DV_LOCAL_DECLARATION, lexicalAnalyzer);
PNodePackage dcl = dr.ReadNextDeclarator();
// â äåêëàðàöèè äîëæíî ïðèñóòñòâîâàòü èìÿ
if( dcl->FindPackage(PC_QUALIFIED_NAME) < 0 )
throw lexicalAnalyzer.LastLexem() ;
// äàëåå ñîçäàåì äåêëàðàöèþ èç ïàêåòà è ïðîâåðÿåì åå
AutoDeclarationCoordinator dcoord(tsl, &*dcl);
PDeclarationMaker dmak = dcoord.Coordinate();
if( !dmak.IsNull() )
dmak->Make();
// ñ÷èòûâàåì èíèöèàëèçàòîð
PExpressionList initList = dr.GetInitializatorList();
if( lexicalAnalyzer.LastLexem() == '=' )
{
// åñëè ñïèñîê èíèöèàëèçàòîðîâ óæå ñ÷èòàí, òî ýòî ñèíòàêñè÷åñêàÿ
// îøèáêà
if( !initList.IsNull() )
throw lexicalAnalyzer.LastLexem();
// ñ÷èòûâàåì ñïèñîê èíèöèàëèçàöèè
else if( lexicalAnalyzer.NextLexem() == '{' )
{
objIator = BodyMakerUtils::MakeObjectInitializator(
ReadInitList(lexicalAnalyzer, dmak, lexicalAnalyzer.LastLexem().GetPos()) );
// ïîñëå òîãî, êàê èíèöèàëèçàòîð è èäåíòèôèêàòîð èçâåñòíû, ñòðîèì äåêëàðàöèþ
insList.push_back( BodyMakerUtils::DeclarationInstructionMaker(
*dynamic_cast<const TypyziedEntity *>(dmak->GetIdentifier()), objIator,
lexicalAnalyzer.LastLexem().GetPos() ) );
// ïðåäîòâðàùàåì ïðîâåðêó èíèöèàëèçàöèè
dmak = NULL;
}
// èíà÷å ñ÷èòûâàåì îáû÷íîå âûðàæåíèå
else
{
lexicalAnalyzer.BackLexem();
ExpressionReader er( lexicalAnalyzer, NULL, true );
er.Read();
initList = new ExpressionList;
initList->push_back(er.GetResultOperand());
}
}
// èíèöèàëèçèðóåì îáúåêò ñïèñêîì çíà÷åíèé. Ñïèñîê çíà÷åíèé
// ìîæåò îòñóòñòâîâàòü, â ýòîì ñëó÷àå ïðîèñõîäèò èíèöèàëèçàöèÿ ïî óìîë÷àíèþ
if( !dmak.IsNull() && dmak->GetIdentifier() != NULL )
{
dmak->Initialize( *initList ),
objIator = BodyMakerUtils::MakeObjectInitializator(initList, *dmak);
insList.push_back( BodyMakerUtils::DeclarationInstructionMaker(
*dynamic_cast<const TypyziedEntity *>(dmak->GetIdentifier()), objIator,
lexicalAnalyzer.LastLexem().GetPos() ) );
}
// ïðîâåðÿåì, åñëè åñòü
if( lexicalAnalyzer.LastLexem() == ';' )
break;
// èíà÷å, åñëè íå ',', âûâîäèì ñèíòàêñè÷åñêóþ îøèáêó
else if( lexicalAnalyzer.LastLexem() != ',' )
throw lexicalAnalyzer.LastLexem();
}
// ïåðåõâàòûâàåì ìåòêó
} catch( const LabelLexem &labLxm ) {
// åñëè ìû â áëîêå è èìååì ñ÷èòàííóþ ìåòêó, ïåðåäàåì åå äàëüøå
// StatementParserImpl
if( inBlock )
throw;
// èíà÷å îáðàáàòûâàåì êàê ñèíòàêñè÷åñêóþ îøèáêó
SyntaxError(labLxm);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
insList.clear();
// ïåðåõâàòûâàåì â îñòàëüíûõ ñëó÷àÿõ
} catch( const Lexem &lxm ) {
SyntaxError(lxm);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
insList.clear(); // î÷èùàåì ñïèñîê â ñëó÷àå ñèíòàêñè÷åñêîé îøèáêè
}
}
// â êîíñòðóêòîð ïîëó÷àåì ïàêåò ñî ñïèñêîì òèïîâ, ïîñëåäíèì
// â êîòîðîì äîëæåí áûòü êëàññ, à òàêæå ëåêñè÷åñêèé àíàëèçàòîð
ClassParserImpl::ClassParserImpl( LexicalAnalyzer &la, NodePackage *np, ClassMember::AS as )
: lexicalAnalyzer(la), typePkg(*np)
{
// 1. ñîçäàåì êëàññ, åñëè îí åùå íå ñîçäàí, à òàêæå ïðîâåðÿåì
// åãî êîððåêòíîñòü
// 2. ñ÷èòûâàåì áàçîâûå òèïû, åñëè ïîñëåäíåé ñ÷èòàííîé ëåêñåìîé
// áûëà ':'
// 3. ïðîâåðÿåì âîçìîæíîñòü îïðåäåëåíèÿ êëàññà â òåêóùåé îáëàñòè âèäèìîñòè
// 4. âñòàâëÿåì îáëàñòè âèäèìîñòè êëàññà, êîòîðûìè îí êâàëèôèöèðîâàí
// â îáúÿâëåíèè è ñàì êëàññ â ñòåê îáëàñòåé âèäèìîñòè
//
// Åñëè íà ýòàïàõ 1 è 3 áûëè çàôèêñèðîâàíû îøèáêè, òåëî êëàññà,
// èãíîðèðóåòñÿ îò '{' äî ñîîòâåòâóþùåé åé '}'
ClassTypeMaker ctm(np, as, GetCurrentSymbolTable(), true);
clsType = ctm.Make(); // êëàññ ìîæåò íå "ïîñòðîèòñÿ", òîãäà clsType == 0
qualifierList = ctm.GetQualifierList();
isUnion = clsType && clsType->GetBaseTypeCode() == BaseType::BT_UNION;
// òðåáóåòñÿ ñ÷èòêà ñïèñêà áàçîâûõ êëàññîâ
if( lexicalAnalyzer.LastLexem() == ':' )
ReadBaseClassList();
// ñèíòàêñè÷åñêàÿ îøèáêà
if( lexicalAnalyzer.LastLexem() != '{' )
throw lexicalAnalyzer.LastLexem();
// åñëè êëàññ íå áûë íàéäåí, ëèáî åãî îïðåäåëåíèå íåâîçìîæíî
// ïðîñòî èãíîðèðóåì âñå òåëî êëàññà
if( clsType == NULL || !CheckerUtils::ClassDefineChecker(
*clsType, qualifierList, GetPackagePosition(np->GetLastChildPackage()) )
)
{
// èãíîðèðóåì òåëî êëàññà
CompoundStatementReader(lexicalAnalyzer, true).Read();
wasRead = true;
}
// èíà÷å âñòàâëÿåì îáëàñòè âèäèìîñòè êëàññà â îáùèé ñòåê,
// ïðè÷åì ãëîáàëüíàÿ îáëàñòü âèäèìîñòè íå äîëæíà âñòàâëÿòüñÿ åñëè îíà åñòü
else
{
wasRead = false;
curAccessSpec = clsType->GetBaseTypeCode() == BaseType::BT_CLASS ?
ClassMember::AS_PRIVATE : ClassMember::AS_PUBLIC;
// åñëè ïåðâàÿ îáëàñòü âèäèìîñòè ãëîáàëüíàÿ, âûíóòü èç ñïèñêà
if( !qualifierList.IsEmpty() && qualifierList[0] ==
::GetScopeSystem().GetFirstSymbolTable() )
qualifierList.PopFront();
// çàãðóæàåì îáëàñòè âèäèìîñòè
::GetScopeSystem().PushSymbolTableList(qualifierList);
// çàãðóæàåì ñàì êëàññ
::GetScopeSystem().MakeNewSymbolTable(clsType);
}
}
// ñ÷èòàòü ÷ëåíû êëàññà
void ClassParserImpl::Parse()
{
// åñëè íå áûëî îøèáêè ïðè îáúÿâëåíèè èìåíè êëàññà, ñ÷èòûâàåì òåëî êëàññà,
// â ïðîòèâíîì ñëó÷àå îíî óæå ñ÷èòàíî
if( wasRead )
return;
// ñ÷èòûâàåì '{'
INTERNAL_IF( lexicalAnalyzer.NextLexem() != '{' );
for( ;; )
{
Lexem lxm = lexicalAnalyzer.NextLexem();
if( lxm == '}' )
break;
else if( lxm == KWPUBLIC || lxm == KWPROTECTED || lxm == KWPRIVATE )
{
if( lexicalAnalyzer.NextLexem() != ':' )
{
SyntaxError(lexicalAnalyzer.LastLexem());
lexicalAnalyzer.BackLexem();
}
curAccessSpec = lxm == KWPUBLIC ? ClassMember::AS_PUBLIC
: (lxm == KWPRIVATE ? ClassMember::AS_PRIVATE : ClassMember::AS_PROTECTED);
}
// åñëè using-äåêëàðàöèÿ
else if( lxm == KWUSING )
{
try {
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(
lexicalAnalyzer).ReadQualifiedConstruction();
MakerUtils::MakeUsingMember( &*nspkg, curAccessSpec );
// ïðîâåðÿåì, åñëè ñ÷èòàëè îïåðàòîð ïðèâåäåíèÿ, çíà÷èò
// ïðîâåðÿåì ïîñëåäíþþ ëåêñåìó
if( nspkg->FindPackage(PC_CAST_OPERATOR) >= 0 )
{
if( lexicalAnalyzer.LastLexem() != ';' )
throw lexicalAnalyzer.LastLexem();
}
else if( lexicalAnalyzer.NextLexem() != ';' )
throw lexicalAnalyzer.LastLexem();
} catch( const Lexem &ep ) {
SyntaxError(ep);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
}
}
// åñëè äåêëàðàöèÿ øàáëîíà
else if( lxm == KWTEMPLATE )
{
}
// èíà÷å ñ÷èòûâàåì ÷ëåí êëàññà
else
{
lexicalAnalyzer.BackLexem();
ParseMember();
}
}
// çàäàåì êëàññó ôëàã, ÷òî îí ïîëíîñòüþ îáúÿâëåí, ò.å. íå ÿâëÿåòñÿ
// íå ïîëíûì
clsType->uncomplete = false;
// ãåíåðèðóåì ñïåöèàëüíûå ôóíêöèè-÷ëåíû, êîòîðûå íå çàäàíû ÿâíî,
// ê-îð ïî óìîë÷àíèþ, ê-îð êîïèðîâàíèÿ, ä-îð, îïåðàòîð êîïèðîâàíèÿ
GenerateSMF();
// îáðàáîòàòü ñ÷èòàííûå inline-ôóíêöèè
LoadInlineFunctions();
// âûòàñêèâàåì âñå îáëàñòè, êîòîðûå áûëè ïîëîæåíû â ñòåê â êîíñòðóêòîðå
// è çàäàåì êëàññó ÷òî îí ñôîðìèðîâàí
for( int i = 0; i<qualifierList.GetSymbolTableCount(); i++ )
::GetScopeSystem().DestroySymbolTable();
// óäàëÿåì ñàì êëàññ èç ñòåêà îáëàñòåé âèäèìîñòè
::GetScopeSystem().DestroySymbolTable();
// çàãðóæàåì friend-ôóíêöèè, ïîñëå òîãî êàê êëàññîâàÿ îáëàñòü âèäèìîñòè
// óäàëåíà.
LoadFriendFunctions();
}
// ñ÷èòàòü ñïèñîê áàçîâûõ òèïîâ è ñîõðàíèòü èõ â êëàññå,
// òàêæå ïðîâåðèòü èõ êîððåêòíîñòü
void ClassParserImpl::ReadBaseClassList()
{
// ñ÷èòûâàåì ':'
INTERNAL_IF( lexicalAnalyzer.NextLexem() != ':' );
// äàëåå ñ÷èòûâàåì ñïèñîê áàçîâûõ êëàññîâ, ïîêà íå ïîÿâèòñÿ '{',
// ëèáî íå áóäåò ñèíòàêñè÷åñêîé îøèáêè
for( ;; )
{
PNodePackage bcp = new NodePackage( PC_BASE_CLASS );
Lexem lxm = lexicalAnalyzer.NextLexem();
if( lxm == KWVIRTUAL )
{
bcp->AddChildPackage( new LexemPackage(lxm) );
lxm = lexicalAnalyzer.NextLexem();
if( lxm == KWPUBLIC || lxm == KWPROTECTED || lxm == KWPRIVATE )
bcp->AddChildPackage( new LexemPackage(lxm) );
else
lexicalAnalyzer.BackLexem();
}
else if( lxm == KWPUBLIC || lxm == KWPROTECTED || lxm == KWPRIVATE )
{
bcp->AddChildPackage( new LexemPackage(lxm) );
lxm = lexicalAnalyzer.NextLexem();
if( lxm == KWVIRTUAL )
bcp->AddChildPackage( new LexemPackage(lxm) );
else
lexicalAnalyzer.BackLexem();
}
else
lexicalAnalyzer.BackLexem();
// ñ÷èòûâàåì èìÿ êëàññà
QualifiedConstructionReader qcr(lexicalAnalyzer, false, true);
bcp->AddChildPackage( qcr.ReadQualifiedConstruction().Release() );
// åñëè êëàññ íå áûë íàéäåí, òî ñîçäàâàòü áàçîâûé êëàññ äëÿ íåãî
// íå íóæíî, ïðîñòî ïðîäîëæàåì ñ÷èòûâàíèå
if( clsType != NULL )
{
// ñîçäàåì áàçîâûé êëàññ
PBaseClassCharacteristic bchar = MakerUtils::MakeBaseClass( &*bcp,
clsType->GetBaseTypeCode() == BaseType::BT_CLASS );
// ìîæåò áûòü NULL, åñëè ïðè ñîçäàíèè áàçîâîãî êëàññà áûëà îøèáêà
if( bchar.IsNull() )
;
// ïðîâåðÿåì, èìååòñÿ ëè êëàññ â ñïèñêå
else if( clsType->baseClassList.HasBaseClass( &bchar->GetPointerToClass() ) >= 0 )
theApp.Error( GetPackagePosition(bcp->GetLastChildPackage()),
"'%s' - êëàññ óæå çàäàí êàê áàçîâûé",
bchar->GetPointerToClass().GetName().c_str());
// èíà÷å äîáàâëÿåì, ïðè ýòîì åñëè êëàññ ïîëèìîðôíûé, òî è ôîðìèðóåìûé
// êëàññ ïîëèìîðôíûé, òàêæå äîáàâëÿåì êîë-âî àáñòðàêòíûõ ìåòîäîâ
else
{
clsType->AddBaseClass(bchar);
const ClassType &bcls = bchar->GetPointerToClass();
if( bcls.IsPolymorphic() )
clsType->polymorphic = true;
clsType->abstractMethodCount += bcls.abstractMethodCount;
}
} // clsType != NULL
// ñëåäóþùàÿ ëåêñåìà äîëæíà áûòü ëèáî ',' ëèáî '{',
lxm = lexicalAnalyzer.NextLexem();
if( lxm != ',' && lxm != '{' )
{
clsType->baseClassList.ClearBaseClassList(); // î÷èùàåì ñïèñîê
throw lxm; // ñèíòàêñè÷åñêàÿ îøèáêà
}
if( lxm == '{' )
{
// ïðîâåðÿåì, åñëè êëàññ ÿâëÿåòñÿ îáúåäèíåíèåì,
// îí íå ìîæåò èìåòü ñïèñêà áàçîâûõ êëàññîâ
if( clsType && clsType->GetBaseTypeCode() == BaseType::BT_UNION &&
!clsType->baseClassList.IsEmpty() )
{
theApp.Error(lxm.GetPos(),
"'%s' - îáúåäèíåíèå íå ìîæåò èìåòü áàçîâûõ êëàññîâ",
clsType->GetName().c_str());
clsType->baseClassList.ClearBaseClassList();
}
lexicalAnalyzer.BackLexem();
break;
}
}
}
// ðàçîáðàòü ÷ëåí
void ClassParserImpl::ParseMember( )
{
NodePackage *tsl = NULL, *dcl = NULL;
DeclaratorReader dr(DV_CLASS_MEMBER, lexicalAnalyzer);
try {
dr.ReadTypeSpecifierList();
tsl = dr.GetTypeSpecPackage().Release();
// â ýòîì ìåñòå ìîæåò áûòü îïðåäåëåíèå êëàññà, åñëè ïîñëåäíèå
// äâà ïàêåòà áûëè êëþ÷ êëàññà è PC_QUALIFIED_NAME, à ïîñëåäíÿÿ
// ñ÷èòàííàÿ ëåêñåìà - '{' èëè ':'
if( NeedClassParserImpl(lexicalAnalyzer.LastLexem(), tsl) )
{
ClassParserImpl cpi(lexicalAnalyzer, tsl, curAccessSpec);
cpi.Parse();
if( lexicalAnalyzer.NextLexem() == ';' )
{
delete tsl;
return;
}
else
lexicalAnalyzer.BackLexem();
}
// èíà÷å åñëè òðåáóåòñÿ ñ÷èòàòü ïåðå÷èñëåíèå, ñ÷èòûâàåì
else if( NeedEnumReading(lexicalAnalyzer.LastLexem(), tsl) )
{
EnumParserImpl epi(lexicalAnalyzer, tsl, curAccessSpec);
epi.Parse();
if( lexicalAnalyzer.NextLexem() == ';' )
{
delete tsl;
return;
}
else
lexicalAnalyzer.BackLexem();
}
// èíà÷å åñëè îáúÿâëåíèå êëàññà èëè ïåðå÷èñëåíèÿ
else if( tsl->GetChildPackageCount() == 2 &&
tsl->GetChildPackage(1)->GetPackageID() == PC_QUALIFIED_NAME &&
lexicalAnalyzer.LastLexem() == ';' )
{
register int pc = tsl->GetChildPackage(0)->GetPackageID() ;
lexicalAnalyzer.NextLexem();
if( pc == KWCLASS || pc == KWSTRUCT || pc == KWUNION )
{
ClassTypeMaker ctm( tsl, curAccessSpec );
ctm.Make();
return;
}
else if( pc == KWENUM )
{
EnumTypeMaker etm( tsl, curAccessSpec );
etm.Make();
return;
}
}
// èíà÷å åñëè îáúÿâëåíèå äðóæåñêîãî êëàññà
else if( tsl->GetChildPackageCount() == 3 &&
tsl->GetChildPackage(0)->GetPackageID() == KWFRIEND &&
(tsl->GetChildPackage(1)->GetPackageID() == KWCLASS ||
tsl->GetChildPackage(1)->GetPackageID() == KWSTRUCT ||
tsl->GetChildPackage(1)->GetPackageID() == KWUNION) &&
tsl->GetChildPackage(2)->GetPackageID() == PC_QUALIFIED_NAME &&
lexicalAnalyzer.LastLexem() == ';' )
{
lexicalAnalyzer.NextLexem();
MakerUtils::MakeFriendClass(tsl);
return;
}
// ñ÷èòûâàåì ñïèñîê äåêëàðàöèé
bool firstDecl = true;
for( ;; )
{
dcl = dr.ReadNextDeclarator().Release();
// çäåñü ïðîâåðÿåì, åñëè äî÷åðíèõ ïàêåòîâ íå ó òèïà íå
// ó äåêëàðàòîðà, çíà÷èò âûõîäèì
if( dcl->IsNoChildPackages() && tsl->IsNoChildPackages() )
throw lexicalAnalyzer.LastLexem();
// äàëåå ñîçäàåì äåêëàðàöèþ èç ïàêåòà è ïðîâåðÿåì åå
MemberDeclarationCoordinator dcoord(tsl, dcl, *clsType, curAccessSpec);
PMemberDeclarationMaker dmak = dcoord.Coordinate();
// ñòðîèòåëü äîëæåí áûòü îïðåäåëåí
if( !dmak.IsNull() )
{
dmak->Make();
// äàëåå èäåò ïðîâåðêà íà òåëî ôóíêöèè, äîëæíû áûòü ñëåä. óñëîâèÿ
// 1. ýòî ïåðâàÿ äåêëàðàöèÿ
// 2. èäåíòèôèêàòîð ÿâëÿåòñÿ ôóíêöèåé
// 3. ïîñëåäíÿÿ ñ÷èòàííàÿ ëåêñåìà - '{', èëè ':', try - åñëè ôóíêöèÿ êîíñòðóêòîð
if( firstDecl )
{
if( NeedFunctionParserImpl(lexicalAnalyzer, dmak->GetIdentifier()) )
{
Function &fn = *const_cast<Function *>(
static_cast<const Function *>(dmak->GetIdentifier()) );
// ñ÷èòûâàåì òåëî â êîíòåéíåð è ñîõðàíÿåì âíóòðè êëàññà,
// ÷òîáû ïî îêîí÷àíèè îïðåäåëåíèÿ êëàññà, ðàçîáðàòü òåëî ìåòîäà
lexicalAnalyzer.BackLexem();
FunctionBodyReader fbr(lexicalAnalyzer, false);
fbr.Read();
// ïîñëå òåëà ìîæåò èäòè ';'
if( lexicalAnalyzer.NextLexem() != ';' )
lexicalAnalyzer.BackLexem();
// ñîõðàíÿåì
methodBodyList.push_back( FnContainerPair(&fn, fbr.GetLexemContainer()) );
return;
}
firstDecl = false;
}
// åñëè èìååì ôóíêöèþ, òî ýòî ìîæåò áûòü òîëüêî ÷èñòûé
// ñïåöèôèêàòîð, ëèáî áåç èíèöèàëèçàöèè, èíà÷å ïîëíûé èíèöèàëèçàòîð
if( const Method *meth = dynamic_cast<const Method *>(dmak->GetIdentifier()) )
{
// äàëåå ìîæåò èäòè çàäàíèå ÷èñòîãî ñïåöèôèêàòîðà äëÿ ìåòîäà
if( lexicalAnalyzer.LastLexem() == '=' )
{
if( lexicalAnalyzer.NextLexem().GetBuf() != "0" )
throw lexicalAnalyzer.LastLexem();
// ïðîâåðÿåì èíèöèàëèçàöèþ
dmak->Initialize( MIT_PURE_VIRTUAL, *ErrorOperand::GetInstance() );
// çàäàåì. ñîîòâ. ïàðàìåòðû êëàññà
if( meth->IsAbstract() )
clsType->abstractMethodCount += 1;
lexicalAnalyzer.NextLexem();
}
// èíà÷å èíèöèàëèçàöèè áåç íè÷åãî, â ýòîì ñëó÷àå âûÿâëÿåì
// âèðòóàëüíîñòü ôóíêöèè â èåðàðõèè
else
{
dmak->Initialize( MIT_NONE, *ErrorOperand::GetInstance() );
}
}
// èíà÷å èíèöèàëèçàöèÿ äàííîãî-÷ëåíà èëè äðóæåñêîé ôóíêöèè,
// â ïîñëåäíåì ñëó÷àå âñåãäà îøèáêà
else if( lexicalAnalyzer.LastLexem() == '=' )
{
ExpressionReader er(lexicalAnalyzer, NULL, true);
er.Read();
// ïðîâåðÿåì èíèöèàëèçàöèþ äàííîãî ÷ëåíà
if( dmak->GetIdentifier() != NULL )
dmak->Initialize( MIT_DATA_MEMBER, *er.GetResultOperand() );
}
// åñëè èäåò ':', âèäèìî èìååì áèòîâîå ïîëå
else if( lexicalAnalyzer.LastLexem() == ':' )
{
ExpressionReader er(lexicalAnalyzer, NULL, true);
er.Read();
// ïðîâåðÿåì ñîçäàíèå áèòîâîãî ïîëÿ
if( dmak->GetIdentifier() != NULL )
dmak->Initialize( MIT_BITFIELD, *er.GetResultOperand() );
}
}
if( lexicalAnalyzer.LastLexem() != ';' &&
lexicalAnalyzer.LastLexem() != ',' )
throw lexicalAnalyzer.LastLexem() ;
if( lexicalAnalyzer.LastLexem() == ';' )
break;
delete dcl;
dcl = NULL;
}
} catch( Lexem &lxm ) {
SyntaxError(lxm);
IgnoreStreamWhileNotDelim(lexicalAnalyzer);
}
delete dcl;
delete tsl;
}
// ïî çàâåðøåíèè îïðåäåëåíèÿ êëàññà, ðàçáèðàåì inline-ôóíêöèè, êîòîðûå
// íàõîäÿòñÿ â êîíòåéíåðå
void ClassParserImpl::LoadInlineFunctions()
{
// åñëè ñïèñîê ïóñòîé, âûéòè
if( methodBodyList.empty() )
return;
list<FnContainerPair>::iterator p = methodBodyList.begin();
while( p != methodBodyList.end() )
{
Function &fn = *(*p).first;
LexemContainer *lc = &*(*p).second;
// ïðîïóñêàåì ïîñòðîéêó, åñëè ô-öèÿ äðóæåñòâåííàÿ. Ýòèì
// áóäåò çàíèìàòüñÿ ô-öèÿ LoadFriendFunctions
if( clsType->GetFriendList().FindClassFriend(&fn) >= 0 )
{
p++;
continue;
}
if( fn.IsHaveBody() )
{
theApp.Error( lc->front().GetPos(),
"'%s' - ó ìåòîäà óæå åñòü òåëî", fn.GetQualifiedName().c_str());
p = methodBodyList.erase(p);
continue;
}
lexicalAnalyzer.LoadContainer( lc ); // çàãðóæàåì êîíòåéíåð
FunctionParserImpl fpi( lexicalAnalyzer, fn );
fpi.Parse();
// óäàëÿåì òåëî, ÷òîáû ïî âòîðîìó çàõîäó îáðàáîòàòü friend-ôóíêöèè
p = methodBodyList.erase(p);
}
}
// çàãðóæàåì äðóæåñòâåííûå ôóíêöèè, ñ÷èòàííûå â ïðîöåññå ïîñòðîéêè êëàññà
void ClassParserImpl::LoadFriendFunctions()
{
// åñëè ñïèñîê ïóñòîé, âûéòè
if( methodBodyList.empty() )
return;
// ïðîõîäèì ïî ñïèñêó çàãðóæàÿ ôóíêöèè
for( list<FnContainerPair>::iterator p = methodBodyList.begin();
p != methodBodyList.end(); p++ )
{
Function &fn = *(*p).first;
LexemContainer *lc = &*(*p).second;
// îáëàñòü âèäèìîñòè äîëæíà áûòü òà æå
INTERNAL_IF( &fn.GetSymbolTableEntry() != &::GetCurrentSymbolTable() );
// ó äðóæåñòâåííîé ô-öèè ìîæåò áûòü òåëî
if( fn.IsHaveBody() )
{
theApp.Error( lc->front().GetPos(),
"'%s' - ó ìåòîäà óæå åñòü òåëî", fn.GetQualifiedName().c_str());
continue;
}
lexicalAnalyzer.LoadContainer( lc ); // çàãðóæàåì êîíòåéíåð
FunctionParserImpl fpi( lexicalAnalyzer, fn );
fpi.Parse();
}
}
// àíàëèçàòîð, ïàêåò ñ ïåðå÷èñëåíèåì, ñïåöèôèêàòîð äîñòóïà åñëè íàõîäèìñÿ âíóòðè êëàññà
void EnumParserImpl::Parse( )
{
EnumTypeMaker ctm(&typePkg, curAccessSpec, true);
enumType = ctm.Make(); // ïåðå÷èñëåíèå ìîæåò íå "ïîñòðîèòñÿ", òîãäà NULL
// åñëè ïåðå÷èñëåíèå íå ñîçäàíî, ëèáî îíî îáúÿâëÿåòñÿ äâàæäû, ëèáî
// îíî îáúÿâëÿåòñÿ íå â ãëîáàëüíîé îáëàñòè âèäèìîñòè
if( enumType == NULL ||
!enumType->IsUncomplete() ||
(!ctm.GetQualifierList().IsEmpty() &&
!(GetCurrentSymbolTable().IsGlobalSymbolTable() ||
GetCurrentSymbolTable().IsNamespaceSymbolTable()) ) )
{
// âûâîäèì îøèáêó
if( enumType != NULL )
theApp.Error(errPos,
"'%s' - %s",
enumType->GetQualifiedName().c_str(),
!enumType->IsUncomplete() ?
"ïåðå÷èñëåíèå óæå îïðåäåëåíî" :
"ïåðå÷èñëåíèå äîëæíî îïðåäåëÿòüñÿ â ãëîáàëüíîé îáëàñòè âèäèìîñòè");
FunctionBodyReader(lexicalAnalyzer, true).Read();
return;
}
// èíà÷å ñ÷èòûâàåì âñå êîíñòàíòû ïåðå÷èñëåíèÿ
Lexem lxm ;
if( lexicalAnalyzer.NextLexem() != '{' )
throw lexicalAnalyzer.LastLexem();
// ñïèñîê êîíñòàíò
EnumConstantList ecl;
int lastVal = -1;
for( ;; )
{
lxm = lexicalAnalyzer.NextLexem();
// ñëåäóþùàÿ êîíñòàíòà
if( lxm == NAME )
{
CharString name = lxm.GetBuf();
lxm = lexicalAnalyzer.NextLexem();
// ñ÷èòûâàåì èíèöèàëèçàòîð
PEnumConstant pec = NULL;
if( lxm == '=' )
{
ExpressionReader er( lexicalAnalyzer, NULL, true);
er.Read();
POperand ival = er.GetResultOperand();
double v;
if( ExpressionMakerUtils::IsInterpretable(ival, v) &&
ExpressionMakerUtils::IsIntegral(ival->GetType()) )
lastVal = v;
else
theApp.Error(errPos,
"'%s' - èíèöèàëèçèðóåìîå çíà÷åíèå äîëæíî áûòü öåëîé êîíñòàíòîé",
name.c_str());
lxm = lexicalAnalyzer.LastLexem();
}
else
lastVal++;
pec = MakerUtils::MakeEnumConstant(name, curAccessSpec, lastVal, errPos,enumType);
if( !pec.IsNull() )
{
ecl.AddEnumConstant(pec);
lastVal = pec->GetConstantValue();
}
// åñëè '{', âûõîäèì
if( lxm == '}' )
break;
// èíà÷å äîëæåí áûòü ','
if( lxm != ',' )
throw lxm;
}
// åñëè êîíåö, âûõîäèì
else if( lxm == '}' )
break;
// èíà÷å ñèíòàêñè÷åñêàÿ îøèáêà
else
throw lxm;
}
enumType->CompleteCreation(ecl);
}
// êîíñòðóêòîð ïðèíèìàåò ôóíêöèþ è ëåêñè÷åñêèé àíàëèçàòîð è
// ñïèñîê îáëàñòåé âèäèìîñòè äëÿ âîññòàíîâëåíèÿ. Ïîñëåäèé ïàðàìåòð ìîæåò
// áûòü ðàâåí 0
FunctionParserImpl::FunctionParserImpl( LexicalAnalyzer &la, Function &fn )
: lexicalAnalyzer(la)
{
fnBody = fn.IsClassMember() && static_cast<Method &>(fn).IsConstructor() ?
new ConstructorFunctionBody(fn, la.LastLexem().GetPos()) :
new FunctionBody(fn, la.LastLexem().GetPos());
// ïðîâåðÿåì, åñëè ó ôóíêöèè óæå åñòü òåëî, âûâåñòè îøèáêó
if( fn.IsHaveBody() )
theApp.Error(la.LastLexem().GetPos(),
"'%s' - ó ôóíêöèè óæå åñòü òåëî", fn.GetQualifiedName().c_str());
// çàäàåì òåëî ôóíêöèè. Òåëî äîëæíî çàäàâàòüñÿ îäèí ðàç
else
fn.SetFunctionBody();
// çàäàåì ôóíêöèîíàëüíóþ îáëàñòü âèäèìîñòè
GetScopeSystem().MakeNewSymbolTable( new FunctionSymbolTable(fn, fn.GetSymbolTableEntry()) );
}
// ñ÷èòàòü ñïèñîê èíèöèàëèçàöèè êîíñòðóêòîðà è âûïîëíèòü íåîáõ. ïðîâåðêè
void FunctionParserImpl::ReadContructorInitList( CtorInitListValidator &cilv )
{
for( unsigned orderNum = 1;; )
{
QualifiedConstructionReader qcr(lexicalAnalyzer, false, true);
PNodePackage id = qcr.ReadQualifiedConstruction();
// íå ìîæåò áûòü óêàçàòåëÿ íà ÷ëåí
if( qcr.IsPointerToMember() )
throw lexicalAnalyzer.LastLexem();
// ñîçäàåì èäåíòèôèêàòîð, ïðåæäå äîñòàíåì ôóíêöèîíàëüíóþ îáëàñòü
// âèäèìîñòè, ò.ê. ýòîãî òðåáóåò ñòàíäàðò
SymbolTable *st = &::GetCurrentSymbolTable();
GetScopeSystem().DestroySymbolTable();
POperand result = IdentifierOperandMaker(*id).Make();
GetScopeSystem().MakeNewSymbolTable(st);
// ñëåäóþùàÿ ëåêñåìà äîëæíà áûòü '('
Lexem lxm = lexicalAnalyzer.NextLexem();
if( lxm != '(' )
throw lxm;
// ñ÷èòûâàåì ñïèñîê âûðàæåíèé
PExpressionList initializatorList = new ExpressionList;
if( lexicalAnalyzer.NextLexem() != ')' )
{
lexicalAnalyzer.BackLexem();
for( ;; )
{
// ñ÷èòûâàåì î÷åðåäíîå âûðàæåíèå
ExpressionReader er(lexicalAnalyzer, NULL, true);
er.Read();
// ñîõðàíÿåì âûðàæåíèå
initializatorList->push_back( er.GetResultOperand() );
if( lexicalAnalyzer.LastLexem() == ')' )
break;
// ïðîâåðÿåì ÷òîáû êîíñòðóêöèÿ áûëà êîððåêòíîé
if( lexicalAnalyzer.LastLexem() != ',' )
throw lexicalAnalyzer.LastLexem();
}
}
// äîáàâëÿåì ÿâíûé èíèöèàëèçàòîð
cilv.AddInitElement(result, initializatorList,
lexicalAnalyzer.LastLexem().GetPos(), orderNum);
// ñ÷èòûâàåì äî '{'
lxm = lexicalAnalyzer.NextLexem();
if( lxm == '{' )
break;
else if( lxm != ',' )
throw lxm;
}
}
// ðàçáîð òåëà ôóíêöèè
void FunctionParserImpl::Parse()
{
register Lexem lxm = lexicalAnalyzer.NextLexem();
INTERNAL_IF( lxm != '{' && lxm != ':' && lxm != KWTRY );
bool isTryRootBlock = false;
// åñëè try-áëîê, ïîñëå íåãî ìîæåò èäòè ñïèñîê èíèöèàëèçàöèè
if( lxm == KWTRY )
{
lxm = lexicalAnalyzer.NextLexem();
isTryRootBlock = true; // óñòàíàâëèâàåì ôëàã, ÷òî êîðíåâîé - try-áëîê
}
// åñëè èìååì òåëî êîíñòðóêòîðà, ïðîâåðÿåì èíèöèàëèçàöèþ ÷ëåíîâ
if( fnBody->IsConstructorBody() )
{
CtorInitListValidator cilv(
static_cast<const ConstructorMethod &>(fnBody->GetFunction()),
lexicalAnalyzer.LastLexem().GetPos() );
// ñ÷èòûâàåì ñïèñîê èíèöèàëèçàöèè êîíñòðóêòîðà
if( lxm == ':' )
ReadContructorInitList(cilv); // ïîñëåäíÿÿ ñ÷èòàííàÿ ëåêñåìà äîëæíà áûòü '{'
// ïðîâåðÿåì èíèöèàëèçàöèþ ÷ëåíîâ
cilv.Validate();
// çàäàåì ñïèñîê èíèöèàëèçàöèè
static_cast<ConstructorFunctionBody &>(*fnBody).
SetConstructorInitList(cilv.GetInitElementList());
}
if( lexicalAnalyzer.LastLexem() != '{' )
throw lexicalAnalyzer.LastLexem();
// çàäàåì êîðíåâóþ êîíñòðóêöèþ
if( isTryRootBlock )
fnBody->SetBodyConstruction(
new TryCatchConstruction(NULL, lexicalAnalyzer.PrevLexem().GetPos()) );
// èíà÷å ñîñòàâíóþ
else
fnBody->SetBodyConstruction(
new CompoundConstruction(NULL, lexicalAnalyzer.PrevLexem().GetPos()) );
// ñîçäàåì êîíòðîëëåð êîíñòðóêöèé
ConstructionController constructionController(fnBody->GetBodyConstruction());
// âûïîëíÿåì ñ÷èòûâàíèå áëîêà
StatementParserImpl spi(lexicalAnalyzer, constructionController, *fnBody);
spi.Parse();
// ïîñëå òîãî êàê òåëî ñôîìðèðîâàíî, âûïîëíÿåì çàêëþ÷èòåëüíûå ïðîâåðêè
PostBuildingChecks(*fnBody).DoChecks();
}
// ñ÷èòàòü è ñîçäàòü using êîíñòðóêöèþ
void StatementParserImpl::ReadUsingStatement( )
{
// using namespace 'name' èëè
// using 'name'
try {
// èñïîëüçîâàíèå îáëàñòè âèäèìîñòè
if( la.NextLexem() == KWNAMESPACE )
{
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(la,
false, true).ReadQualifiedConstruction();
MakerUtils::MakeUsingNamespace( &*nspkg );
if( la.NextLexem() != ';' )
throw la.LastLexem();
}
// èíà÷å using-äåêëàðàöèÿ
else
{
la.BackLexem();
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(la).ReadQualifiedConstruction();
MakerUtils::MakeUsingNotMember( &*nspkg );
if( la.NextLexem() != ';' )
throw la.LastLexem();
}
} catch( const Lexem &ep ) {
SyntaxError(ep);
IgnoreStreamWhileNotDelim(la);
}
}
// ñ÷èòàòü for êîíñòðóêöèþ
ForConstruction *StatementParserImpl::ReadForConstruction( ConstructionController &cntCtrl )
{
Position fpos = la.LastLexem().GetPos();
if( la.NextLexem() != '(' )
throw la.LastLexem();
InstructionList init;
PInstruction cond = NULL;
POperand iter = NULL;
if( la.NextLexem() != ';' )
{
// ñ÷èòûâàåì ñåêöèþ èíèöèàëèçàöèè
la.BackLexem();
InstructionParserImpl ipl(la, init);
ipl.Parse();
init = ipl.GetInstructionList();
}
if( la.NextLexem() != ';' )
{
la.BackLexem();
cond = ReadCondition();
if( la.LastLexem() != ';' )
throw la.LastLexem();
}
if( la.NextLexem() != ')' )
{
la.BackLexem();
iter = ReadExpression();
if( la.LastLexem() != ')' )
throw la.LastLexem();
}
return BodyMakerUtils::ForConstructionMaker( ForInitSection(init), cond, iter,
controller.GetCurrentConstruction(), fpos) ;
}
// ñ÷èòàòü âûðàæåíèå äëÿ êîíñòðóêöèé, âåðíóòü ðåçóëüòàò
POperand StatementParserImpl::ReadExpression( bool noComa )
{
ExpressionReader er(la, NULL, noComa);
er.Read();
return er.GetResultOperand();
}
// ñ÷èòàòü èíñòðóêöèþ. Èíñòðóêöèåé ÿâëÿåòñÿ äåêëàðàöèÿ ñ èíèöèàëèçàöèåé
// èëè âûðàæåíèå. Èñïîëüçóåòñÿ â if, switch, while, for
PInstruction StatementParserImpl::ReadCondition( )
{
TypeExpressionReader ter(la);
ter.Read( false, false );
Position insPos = la.LastLexem().GetPos();
// ïðîâåðÿåì ïàêåò,
INTERNAL_IF( ter.GetResultPackage() == NULL );
// åñëè èìååì âûðàæåíèå, çíà÷èò ñòðîèì âûðàæåíèå
if( ter.GetResultPackage()->IsExpressionPackage() )
{
POperand exp = static_cast<const ExpressionPackage &>(
*ter.GetResultPackage()).GetExpression();
delete ter.GetResultPackage();
return new ExpressionInstruction(exp, insPos);
}
// èíà÷å èìååì äåêëàðàöèþ, ñëåäóåò ñ÷èòàòü èíèöèàëèçàòîð
else
{
if( la.LastLexem() != '=' )
throw la.LastLexem();
// åñëè èíèöèàëèçàòîð çàäàí â ñêîáêàõ, ýòî îøèáêà
if( !ter.GetInitializatorList().IsNull() )
theApp.Error(la.LastLexem().GetPos(), "èíèöèàëèçàòîð óæå çàäàí");
POperand iator = ReadExpression();
// ñòðîèì èíñòðóêöèþ
PInstruction cond = BodyMakerUtils::MakeCondition(
static_cast<const NodePackage &>(*ter.GetResultPackage()), iator, insPos);
delete ter.GetResultPackage();
return cond;
}
}
// ñ÷èòàòü catch-äåêëàðàöèþ
PTypyziedEntity StatementParserImpl::ReadCatchDeclaration( )
{
if( la.NextLexem() != '(' )
throw la.LastLexem();
// ñ÷èòûâàåì òèï, åñëè íå ñ÷èòàíî '...'
if( la.NextLexem() == ELLIPSES )
{
// ñëåä. ëåêñåìà äîëæíà áûòü ')'
if( la.NextLexem() != ')' )
throw la.LastLexem();
return NULL;
}
else
{
Position dpos = la.LastLexem().GetPos();
// ñ÷èòûâàåì äåêëàðàöèþ
la.BackLexem();
DeclaratorReader dr( DV_CATCH_DECLARATION, la, true );
dr.ReadTypeSpecifierList();
PNodePackage typeLst = dr.GetTypeSpecPackage();
// åñëè íå áûëî ñ÷èòàíî òèïà, îøèáêà
if( typeLst->IsNoChildPackages() )
throw la.LastLexem();
// ñ÷èòûâàåì äåêëàðàòîð
PNodePackage decl = dr.ReadNextDeclarator();
if( la.LastLexem() != ')' )
throw la.LastLexem();
// ñòðîèì äåêëàðàöèþ, âîçâðàùàåì
return CatchDeclarationMaker(*typeLst, *decl, dpos).Make();
}
}
// ñ÷èòàòü ñïèñîê catch-îáðàáîò÷èêîâ
void StatementParserImpl::ReadCatchList()
{
for( ;; )
{
if( la.NextLexem() != KWCATCH )
{
la.BackLexem();
break;
}
Position cpos = la.LastLexem().GetPos();
// ñîçäàåì îáëàñòü âèäèìîñòè äëÿ catch-áëîêà
MakeLST();
// ñ÷èòûâàåì catch-äåêëàðàöèþ
PTypyziedEntity catchObj = ReadCatchDeclaration();
if( la.NextLexem() != '{' )
throw la.LastLexem();
// ñòðîèì catch-êîíñòðóêöèþ
CatchConstruction *cc = CatchConstructionMaker(
catchObj, controller.GetCurrentConstruction(), cpos).Make();
PBodyComponent pCatch = cc;
// ñ÷èòûâàåì catch-áëîê, ñîõðàíÿåì åãî â catch-êîíñòðóêöèè
cc->AddChildComponent( ParseBlock() );
// âîññòàíàâëèâàåì îáëàñòü âèäèìîñòè è òåêóùóþ êîíñòðóêöèþ
GetScopeSystem().DestroySymbolTable();
controller.SetCurrentConstruction( cc->GetParentConstruction() );
pCatch.Release();
}
}
// ñ÷èòàòü áëîê
CompoundConstruction *StatementParserImpl::ParseBlock( )
{
INTERNAL_IF( la.LastLexem() != '{' );
// ñîõðàíÿåì òåêóùóþ ÎÂ è òåêóùóþ êîíñòðóêèöþ,
// äëÿ òîãî ÷òîáû â ñëó÷àå îøèáêè âîññòàíîâèòü èõ
const SymbolTable &cur = GetCurrentSymbolTable();
Construction &parent = controller.GetCurrentConstruction();
// ñîçäàåì ñîñòàâíó. êîíñòðóêöèþ, äåëàåì åå òåêóùåé
CompoundConstruction *compound =
BodyMakerUtils::SimpleConstructionMaker<CompoundConstruction>(
parent, la.LastLexem().GetPos() );
controller.SetCurrentConstruction(compound);
while( la.NextLexem() != '}' )
{
la.BackLexem();
// ïðè ñ÷èòûâàíèè êîìïîíåíòà ìîãóò âîçíèêàòü
// ñèíòàêñè÷åñêèå îøèáêè
try {
compound->AddChildComponent( ParseComponent() );
} catch( const Lexem &lxm ) {
// âîññòàíîâèì òåêóùóþ êîíñòðóêöèþ, âîññòàíîâèì îáëàñòü âèäèìîñòè
controller.SetCurrentConstruction(compound);
while( &GetCurrentSymbolTable() != &cur )
{
GetScopeSystem().DestroySymbolTable();
INTERNAL_IF( GetCurrentSymbolTable().IsGlobalSymbolTable() );
}
SyntaxError(lxm);
IgnoreStreamWhileNotDelim(la);
}
}
// âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ
controller.SetCurrentConstruction(&parent);
return compound;
}
// ñ÷èòàòü êîìïîíåíò ôóíêöèè
BodyComponent *StatementParserImpl::ParseComponent( )
{
using namespace BodyMakerUtils;
// êîíòðîëèðóåì ïåðåïîëíåíèå ñòåêà
OverflowStackController osc(la);
PBodyComponent pComp = NULL; // êîìïîíåíò, êîòîðûé ñ÷èòûâàåòñÿ
// ñ÷èòûâàåì ñëåäóþùóþ ëåêñåìó
register int lcode = la.NextLexem();
Position compPos = la.LastLexem().GetPos();
// ïóñòàÿ èíñòðóêöèÿ
if( lcode == ';' )
return SimpleComponentMaker<EmptyInstruction>(compPos);
// using-äåêëàðàöèÿ èëè using-namespace
else if( lcode == KWUSING )
{
ReadUsingStatement();
// ñîçäàåì ïóñòóþ èíñòðóêöèþ â êà÷åñòâå çàìåíû using-äåêëàðàöèè
return SimpleComponentMaker<EmptyInstruction>(compPos);
}
// namespace-àëèàñ
else if( lcode == KWNAMESPACE )
{
// ñ÷èòûâàåì èìÿ îáëàñòè âèäèìîñòè è ïåðåäàåì åãî â ñòðîèòåëü
// îáëàñòè âèäèìîñòè
PNodePackage nspkg = QualifiedConstructionReader(
la, true, true).ReadQualifiedConstruction();
if( la.NextLexem() != '=' )
throw la.LastLexem();
// èíà÷å ñ÷èòûâàåì ñèíîíèì îáëàñòè âèäèìîñòè
MakerUtils::MakeNamespaceAlias( &*nspkg, &*QualifiedConstructionReader(
la, false, true).ReadQualifiedConstruction());
if( la.NextLexem() != ';' )
throw la.LastLexem();
// ñîçäàåì ïóñòóþ èíñòðóêöèþ â êà÷åñòâå çàìåíû namespace-äåêëàðàöèè
return SimpleComponentMaker<EmptyInstruction>(compPos);
}
// case âûðàæåíèå: êîìïîíåíò
else if( lcode == KWCASE )
{
POperand exp = ReadExpression( true );
if( la.LastLexem() != ':' )
throw la.LastLexem();
// ñ÷èòûâàåì îïÿòü êîìïîíåíò
BodyComponent &bc = *ParseComponent( );
return CaseLabelMaker(exp, bc, controller.GetCurrentConstruction(), compPos);
}
// default: êîìïîíåíò
else if( lcode == KWDEFAULT )
{
if( la.NextLexem() != ':' )
throw la.LastLexem();
BodyComponent &bc = *ParseComponent( );
return DefaultLabelMaker(bc, controller.GetCurrentConstruction(), compPos);
}
// asm ( ñòðîêà ) ;
else if( lcode == KWASM )
{
if( la.NextLexem() != '(' )
throw la.LastLexem();
Lexem lxm = la.NextLexem(); // ñîõðàíÿåì ñòðîêîâûé ëèòåðàë
if( lxm != STRING || la.NextLexem() != ')' )
throw la.LastLexem();
if( la.NextLexem() != ';' )
throw la.LastLexem();
return AsmOperationMaker(lxm.GetBuf(), compPos);
}
// return âûðàæåíèå? ;
else if( lcode == KWRETURN )
{
POperand exp = NULL;
if( la.NextLexem() == ';' )
;
else
{
la.BackLexem();
exp = ReadExpression();
if( la.LastLexem() != ';' )
throw la.LastLexem() ;
}
return ReturnOperationMaker(exp, fnBody.GetFunction(), compPos);
}
// break;
else if( lcode == KWBREAK )
{
if( la.NextLexem() != ';' )
throw la.LastLexem();
return BreakOperationMaker( controller.GetCurrentConstruction(), compPos);
}
// continue;
else if( lcode == KWCONTINUE )
{
if( la.NextLexem() != ';' )
throw la.LastLexem();
return ContinueOperationMaker( controller.GetCurrentConstruction(), compPos);
}
// goto ìåòêà;
else if( lcode == KWGOTO )
{
Lexem lxm = la.NextLexem();
if( lxm != NAME )
throw la.LastLexem();
if( la.NextLexem() != ';' )
throw la.LastLexem();
return GotoOperationMaker( lxm.GetBuf(), fnBody, compPos );
}
// do êîìïîíåíò while( âûðàæåíèå ) ;
else if( lcode == KWDO )
{
// ñîçäàåì îáëàñòü âèäèìîñòè äëÿ do
MakeLST();
// ñîçäàåì do
DoWhileConstruction *dwc = SimpleConstructionMaker<DoWhileConstruction>(
controller.GetCurrentConstruction(), compPos);
pComp = dwc;
// çàäàåì êàê òåêóùóþ
controller.SetCurrentConstruction(dwc);
// ñ÷èòàòü êîìïîíåíò
PBodyComponent doChild = ParseComponent();
if( la.NextLexem() != KWWHILE )
throw la.LastLexem();
if( la.NextLexem() != '(' )
throw la.LastLexem();
POperand doExpr = ReadExpression();
if( la.LastLexem() != ')' )
throw la.LastLexem();
if( la.NextLexem() != ';' )
throw la.LastLexem();
// çàäàåì âûðàæåíèå do-êîíñòðóêöèè, ïðîâåðÿåì âûðàæåíèå,
// ïðèñîåäèíÿåì äî÷åðíèé êîìïîíåíò, âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ,
// âîññòàíàâëèâàåì ÎÂ
dwc->SetCondition(doExpr);
ValidCondition(doExpr, "do", compPos);
dwc->AddChildComponent( doChild.Release() );
controller.SetCurrentConstruction( dwc->GetParentConstruction() );
GetScopeSystem().DestroySymbolTable();
return pComp.Release(); // âîçâðàùàåì do-êîíñòðóêöèþ
}
// for( èíèöèàëèçàöèÿ? ; ñðàâíåíèå? ; âûðàæåíèå? ) êîìïîíåíò
else if( lcode == KWFOR )
{
// ñîçäàåì îáëàñòü âèäèìîñòè äëÿ êîíñòðóêöèè
MakeLST();
// ñ÷èòûâàåì è ñîçäàåì ñàìó êîíñòðóêöèþ
ForConstruction *fc = ReadForConstruction(controller);
pComp = fc;
// çàäàåì êàê òåêóùóþ
controller.SetCurrentConstruction(fc);
BodyComponent *forChild = ParseComponent();
// ïðèñîåäèíÿåì äî÷åðíèé êîìïîíåíò, âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ,
// âîññòàíàâëèâàåì ÎÂ
fc->AddChildComponent( forChild );
controller.SetCurrentConstruction( fc->GetParentConstruction() );
GetScopeSystem().DestroySymbolTable();
// âåðíóòü for-êîíñòðóêöèþ
return pComp.Release();
}
// while( ñðàâíåíèå ) êîìïîíåíò
else if( lcode == KWWHILE )
{
// ñîçäàåì îáëàñòü âèäèìîñòè äëÿ êîíñòðóêöèè
MakeLST();
if( la.NextLexem() != '(' )
throw la.LastLexem();
PInstruction whileCond = ReadCondition();
if( la.LastLexem() != ')' )
throw la.LastLexem();
// ñîçäàåì while-êîíñòðóêöèþ, ïðîâåðÿåì êîððåêòíîñòü âûðàæåíèÿ
WhileConstruction *wc = ConditionConstructionMaker<WhileConstruction>(whileCond,
controller.GetCurrentConstruction(), compPos);
ValidCondition(whileCond, "while");
pComp = wc;
// çàäàåì êàê òåêóùóþ
controller.SetCurrentConstruction(wc);
BodyComponent *whileChild = ParseComponent();
// ïðèñîåäèíÿåì äî÷åðíèé êîìïîíåíò, âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ,
// âîññòàíàâëèâàåì ÎÂ
wc->AddChildComponent( whileChild );
controller.SetCurrentConstruction( wc->GetParentConstruction() );
GetScopeSystem().DestroySymbolTable();
// âåðíóòü while-êîíñòðóêöèþ
return pComp.Release();
}
// switch( ñðàâíåíèå ) êîìïîíåíò
else if( lcode == KWSWITCH )
{
// ñîçäàåì îáëàñòü âèäèìîñòè äëÿ êîíñòðóêöèè
MakeLST();
if( la.NextLexem() != '(' )
throw la.LastLexem();
PInstruction switchCond = ReadCondition();
if( la.LastLexem() != ')' )
throw la.LastLexem();
// ñîçäàåì swicth-êîíñòðóêöèþ, ïðîâåðÿåì êîððåêòíîñòü âûðàæåíèÿ
SwitchConstruction *sc = ConditionConstructionMaker<SwitchConstruction>(switchCond,
controller.GetCurrentConstruction(), compPos);
ValidCondition(switchCond, "switch", true);
pComp = sc;
// çàäàåì êàê òåêóùóþ
controller.SetCurrentConstruction(sc);
BodyComponent *switchChild = ParseComponent();
// ïðèñîåäèíÿåì äî÷åðíèé êîìïîíåíò, âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ,
// âîññòàíàâëèâàåì ÎÂ
sc->AddChildComponent( switchChild );
controller.SetCurrentConstruction( sc->GetParentConstruction() );
GetScopeSystem().DestroySymbolTable();
// âåðíóòü swicth-êîíñòðóêöèþ
return pComp.Release();
}
// if( ñðàâíåíèå ) êîìïîíåíò [else êîìïîíåíò]?
else if( lcode == KWIF )
{
// ñîçäàåì îáëàñòü âèäèìîñòè äëÿ êîíñòðóêöèè
MakeLST();
if( la.NextLexem() != '(' )
throw la.LastLexem();
PInstruction ifCond = ReadCondition();
if( la.LastLexem() != ')' )
throw la.LastLexem();
// ñîçäàåì if-êîíñòðóêöèþ, ïðîâåðÿåì êîððåêòíîñòü âûðàæåíèÿ
IfConstruction *ic = ConditionConstructionMaker<IfConstruction>(ifCond,
controller.GetCurrentConstruction(), compPos);
ValidCondition(ifCond, "if");
pComp = ic;
// çàäàåì êàê òåêóùóþ
controller.SetCurrentConstruction(ic);
BodyComponent *ifChild = ParseComponent();
// ïðèñîåäèíÿåì äî÷åðíèé êîìïîíåíò
ic->AddChildComponent( ifChild );
// åñëè åñòü else
if( la.NextLexem() == KWELSE )
{
ElseConstruction *ec = SimpleConstructionMaker<ElseConstruction>(
const_cast<Construction&>(*ic->GetParentConstruction()), compPos);
PBodyComponent pElse = ec;
// çàäàåì êàê òåêóùóþ
controller.SetCurrentConstruction(ic);
BodyComponent *elseChild = ParseComponent();
// ïðèñîåäèíÿåì äî÷åðíèé êîìïîíåíò, ïðèñîåäèíÿåì ê if
ec->AddChildComponent(elseChild);
ic->SetElseConstruction( ec );
// îñâîáîæäàåì èíòåëëåêòóàëüíûé óêàçàòåëü êîòîðûé õðàíèò else
pElse.Release();
}
else
la.BackLexem();
// âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ, âîññòàíàâëèâàåì ÎÂ
controller.SetCurrentConstruction( ic->GetParentConstruction() );
GetScopeSystem().DestroySymbolTable();
// âåðíóòü if-êîíñòðóêöèþ
return pComp.Release();
}
// try áëîê ñïèñîê-îáðàáîò÷èêîâ
else if( lcode == KWTRY )
{
if( la.NextLexem() != '{' )
throw la.LastLexem();
// ñîçäàåì try êîíñòðóêöèþ
TryCatchConstruction *tcc = SimpleConstructionMaker<TryCatchConstruction>(
controller.GetCurrentConstruction(), compPos);
pComp = tcc;
// çàäàåì êàê òåêóùóþ, ñ÷èòûâàåì áëîê, äîáàâëÿåì áëîê
controller.SetCurrentConstruction(tcc);
BodyComponent *block = ParseBlock();
tcc->AddChildComponent(block);
if( la.NextLexem() != KWCATCH )
theApp.Error(la.LastLexem().GetPos(), "try áåç îáðàáîò÷èêîâ");
else
{
la.BackLexem();
ReadCatchList();
}
// âîññòàíàâëèâàåì ðîäèòåëüñêóþ êîíñòðóêöèþ, âîçâðàùàåì try-áëîê
controller.SetCurrentConstruction( tcc->GetParentConstruction() );
return pComp.Release();
}
// áëîê
else if( lcode == '{' )
{
bool isMade = BodyMakerUtils::MakeLocalSymbolTable( controller.GetCurrentConstruction() );
CompoundConstruction *cc = ParseBlock();
if( isMade )
GetScopeSystem().DestroySymbolTable();
return cc;
}
// åñëè '}', àâàðèéíîå çàâðøåíèå êîìïèëÿöèè
else if( lcode == '}' )
theApp.Fatal( la.LastLexem().GetPos(), "àâàðèéíîå çàâåðøåíèå êîìïèëÿöèè ïåðåä '}'" );
// êîíåö ôàéëà
else if( lcode == EOF )
theApp.Fatal( la.LastLexem().GetPos(), "íåîæèäàííûé êîíåö ôàéëà" );
// èíñòðóêöèÿ: âûðàæåíèå, äåêëàðàöèÿ, äåêëàðàöèÿ êëàññà, ìåòêà
else
{
la.BackLexem();
InstructionList insList; // âûõîäíîé ñïèñîê èíñòðóêöèé
InstructionParserImpl ipl(la, insList, true);
// ìîæåì ïåðåõâàòèòü ìåòêó
try {
ipl.Parse();
return InstructionListMaker( ipl.GetInstructionList(), compPos );
} catch( const LabelLexem &labLxm ) {
// ñîçäàåì ìåòêó
Label label( labLxm.GetBuf(),
const_cast<FunctionSymbolTable *>(GetScopeSystem().GetFunctionSymbolTable()),
labLxm.GetPos() );
// ïåðåõâàòèëè ìåòêó, ñ÷èòûâàåì êîìïîíåíò
return SimpleLabelMaker(label, *ParseComponent(), fnBody, compPos);
}
}
// âñåãäà îøèáêà, åñëè äîõîäèì äî ñþäà
INTERNAL("'StatementParserImpl::ParseComponent' - îøèáêà â ñòðîèòåëüñòâå êîìïîíåíòà");
return NULL;
}
// ñ÷èòàòü áëîê èëè try-áëîê, â çàâèñèìîñòè îò êîðíåâîé êîíñòðóêöèè
void StatementParserImpl::Parse() {
// çíà÷èò ñ÷èòûâàåì áëîê, à çà íèì catch-îáðàáîò÷èêè
if( controller.GetCurrentConstruction().GetConstructionID() == Construction::CC_TRY )
{
TryCatchConstruction &tcc = static_cast<TryCatchConstruction &>(
controller.GetCurrentConstruction());
// ñ÷èòûâàåì áëîê
BodyComponent *block = ParseBlock();
tcc.AddChildComponent(block);
if( la.NextLexem() != KWCATCH )
theApp.Error(la.LastLexem().GetPos(), "try áåç îáðàáîò÷èêîâ");
else
{
la.BackLexem();
try {
ReadCatchList();
} catch( const Lexem &lxm ) {
theApp.Fatal(lxm.GetPos(), "àâàðèéíîå çàâåðøåíèå êîìïèëÿöèè ïåðåä '%s'",
lxm.GetBuf().c_str());
}
}
}
// èíà÷å ñ÷èòûâàåì ïðîñòî áëîê
else
ParseBlock();
}
// âûâåñòè ñèíòàêñè÷åñêóþ îøèáêó îáíàðóæåííóþ ðÿäîì ñ ëåêñåìîé 'lxm'
void ParserUtils::SyntaxError( const Lexem &lxm )
{
theApp.Error(
lxm.GetPos(), "ñèíòàêñè÷åñêàÿ îøèáêà ïåðåä '%s'", lxm.GetBuf().c_str());
}
// ôóíêöèÿ ñ÷èòûâàåò ëåêñåìû äî òåõ ïîð ïîêà íå ïîÿâèòñÿ ';'
void ParserUtils::IgnoreStreamWhileNotDelim( LexicalAnalyzer &la )
{
Lexem lxm;
for( ;; )
{
lxm = la.NextLexem();
if( lxm == EOF )
theApp.Fatal( lxm.GetPos(), "íåîæèäàííûé êîíåö ôàéëà" );
else if( lxm == '{' || lxm == '}' )
theApp.Fatal( lxm.GetPos(), "àâàðèéíîå çàâåðøåíèå êîìïèÿëöèè ïåðåä '%c'",
(char)lxm);
else if( lxm == ';' )
break;
}
}
// ïîëó÷èòü ïîçèöèþ ïàêåòà
Position ParserUtils::GetPackagePosition( const Package *pkg )
{
INTERNAL_IF( pkg == NULL );
for( ;; )
{
if( pkg->IsLexemPackage() )
return ((LexemPackage *)pkg)->GetLexem().GetPos();
else if( pkg->IsNodePackage() )
{
NodePackage *np = (NodePackage *)pkg;
if( np->IsNoChildPackages() )
INTERNAL( "'ParserUtils::GetPackagePosition' - íåò äî÷åðíèõ ïàêåòîâ" );
else
pkg = np->GetChildPackage(0);
}
else
INTERNAL( "'ParserUtils::GetPackagePosition' - íåèçâåñòíûé òèï ïàêåòà" );
}
return Position();
}
// ðàñïå÷àòàòü âñå äåðåâî ïàêåòîâ, âåðíóòü áóôåð
CharString ParserUtils::PrintPackageTree( const NodePackage *np )
{
string outbuf;
INTERNAL_IF( np == NULL );
for( int i = 0; i<np->GetChildPackageCount(); i++ )
{
const Package *pkg = np->GetChildPackage(i);
if( pkg->IsLexemPackage() )
outbuf += ((LexemPackage *)pkg)->GetLexem().GetBuf().c_str();
else if( pkg->IsNodePackage() )
outbuf += PrintPackageTree( (NodePackage *)pkg ).c_str();
else if( pkg->IsExpressionPackage() )
;
else
INTERNAL( "'ParserUtils::GetPackagePosition' - íåèçâåñòíûé òèï ïàêåòà" );
}
return outbuf.c_str();
}
// ïðîâåðÿåò, åñëè âõîäíîé ïàêåò è ëåêñ. íàõîäèòñÿ â ñîñòîÿíèè
// äåêëàðàöèè òèïà (êëàññ, ïåðå÷èñëåíèå), ñ÷èòàòü òèï, âûïîëíèòü
// äåêëàðàöèþ âåðíóòü. Åñëè íå òðåáóåòñÿ ñ÷èòûâàòü äåêëàðàòîðû, âåðíóòü true, èíà÷å false
bool ParserUtils::LocalTypeDeclaration(
LexicalAnalyzer &lexicalAnalyzer, NodePackage *pkg, const BaseType *&outbt )
{
// â ýòîì ìåñòå ìîæåò áûòü îïðåäåëåíèå êëàññà, åñëè ïîñëåäíèå
// äâà ïàêåòà áûëè êëþ÷ êëàññà è PC_QUALIFIED_NAME, à ïîñëåäíÿÿ
// ñ÷èòàííàÿ ëåêñåìà - '{' èëè ':'
if( NeedClassParserImpl(lexicalAnalyzer.LastLexem(), pkg) )
{
ClassParserImpl cpi(lexicalAnalyzer, pkg, ClassMember::NOT_CLASS_MEMBER);
cpi.Parse();
outbt = &cpi.GetClassType();
if( lexicalAnalyzer.NextLexem() == ';' )
return true;
else
lexicalAnalyzer.BackLexem();
}
// èíà÷å åñëè òðåáóåòñÿ ñ÷èòàòü ïåðå÷èñëåíèå, ñ÷èòûâàåì
else if( NeedEnumReading(lexicalAnalyzer.LastLexem(), pkg) )
{
EnumParserImpl epi(lexicalAnalyzer, pkg, ClassMember::NOT_CLASS_MEMBER);
epi.Parse();
outbt = &epi.GetEnumType();
if( lexicalAnalyzer.NextLexem() == ';' )
return true;
else
lexicalAnalyzer.BackLexem();
}
// èíà÷å åñëè îáúÿâëåíèå êëàññà èëè ïåðå÷èñëåíèÿ
else if( pkg->GetChildPackageCount() == 2 &&
pkg->GetChildPackage(1)->GetPackageID() == PC_QUALIFIED_NAME &&
lexicalAnalyzer.LastLexem() == ';' )
{
register int pc = pkg->GetChildPackage(0)->GetPackageID() ;
lexicalAnalyzer.NextLexem();
if( pc == KWCLASS || pc == KWSTRUCT || pc == KWUNION )
{
ClassTypeMaker ctm( pkg, ClassMember::NOT_CLASS_MEMBER );
outbt = ctm.Make();
}
else if( pc == KWENUM )
{
EnumTypeMaker etm( pkg, ClassMember::NOT_CLASS_MEMBER );
outbt = etm.Make();
}
else
return false;
return true;
}
return false;
}
// ïðîâåðÿåò ïî èäåíòèôèêàòîðó è ïîñëåäíåé ñ÷èòàííîé ëåêñåìå, íåîáõîäèì
// ëè ôóíêöèè ðàçáîð òåëà
inline static bool NeedFunctionParserImpl( LexicalAnalyzer &la, const Identifier *id )
{
const Function *fn = dynamic_cast<const Function *>(id);
register Lexem lastLxm = la.LastLexem();
if( (lastLxm == '{' ||
(dynamic_cast<const ConstructorMethod *>(fn) &&
(lastLxm == ':' || lastLxm == KWTRY)) ) && fn != NULL )
return true;
return false;
}
// ïðîâåðÿåò ïî ïàêåòó, è ïîñëåäíåé ñ÷èòàííîé ëåêñåìå, âîçìîæíî
// ëè îïðåäåëåíèå êëàññà
inline static bool NeedClassParserImpl( const Lexem &lastLxm, const NodePackage *np )
{
if( np->IsNoChildPackages() )
return false;
int lid = np->GetLastChildPackage()->GetPackageID();
if( lid == KWCLASS || lid == KWSTRUCT || lid == KWUNION ) // áåçèìÿííîå îáúÿâëåíèå
{
if( lastLxm == '{' ||
lastLxm == ':' )
return true;
return false;
}
if( lid != PC_QUALIFIED_NAME || np->GetChildPackageCount() < 2 )
return false;
int preid = np->GetChildPackage(np->GetChildPackageCount()-2)->GetPackageID(),
lcode = lastLxm;
return (preid == KWCLASS || preid == KWSTRUCT || preid == KWUNION) &&
(lcode == '{' || lcode == ':') ;
}
// ïðîâåðÿåò ïî ïàêåòó, è ïîñëåäíåé ñ÷èòàííîé ëåêñåìå, òðåáóåòñÿ ëè
// îïðåäåëåíèå ïåðå÷èñëåíèÿ
inline static bool NeedEnumReading( const Lexem &lastLxm, const NodePackage *np )
{
if( np->IsNoChildPackages() )
return false;
int lid = np->GetLastChildPackage()->GetPackageID();
if( lid == KWENUM ) // áåçèìÿííîå îáúÿâëåíèå
return lastLxm == '{';
if( lid != PC_QUALIFIED_NAME || np->GetChildPackageCount() < 2 )
return false;
int preid = np->GetChildPackage(np->GetChildPackageCount()-2)->GetPackageID(),
lcode = lastLxm;
return (preid == KWENUM && lcode == '{');
}
// ñ÷èòàòü ñïèñîê èíèöèàëèçàöèè è âûïîëíèòü ïðîâåðêó
inline static ListInitComponent *ReadInitList( LexicalAnalyzer &la,
PDeclarationMaker &pdm, const Position &errPos )
{
// ñ÷èòûâàåì
InitializationListReader ilr(la);
ilr.Read();
INTERNAL_IF( ilr.GetListInitComponent() == NULL );
// ïðîâåðÿåì, ÷òîáû èíèöèàëèçàòîð áûë îáúåêòîì
if( pdm.IsNull() || pdm->GetIdentifier() == NULL )
return const_cast<ListInitComponent *>(ilr.GetListInitComponent());
else if( const Object *ob = dynamic_cast<const ::Object *>(pdm->GetIdentifier()) )
{
ListInitializationValidator( *ilr.GetListInitComponent(),
errPos, const_cast<::Object &>(*ob) ).Validate();
// âåðíóòü ñïèñîê äëÿ ãåíåðàöèè
return const_cast<ListInitComponent *>(ilr.GetListInitComponent());
}
// èíà÷å ïðîâåðÿåì èíèöèàëèçàöèþ ñïèñêîì
else
{
theApp.Error(errPos, "èíèöèàëèçàöèÿ ñïèñêîì íå-îáúåêòà");
return const_cast<ListInitComponent *>(ilr.GetListInitComponent());
}
}
You can’t perform that action at this time.