Files
Client/Server/RylServerProject/ScriptEngine/SyntaxTree.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

548 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "SyntaxTree.h"
#include "SymbolTable.h"
#include "lex.h"
#include <assert.h>
#include <set>
///////////////////////////////////////////////////////////////////////////////
// Àü¿ªº¯¼ö
CSyntaxTree * g_pSynTree = 0;
CSymbolTable * g_pSymbolTable = 0;
char szBuffer[4096];
///////////////////////////////////////////////////////////////////////////////
// Parser ÇÔ¼ö
void yyerror( char *msg )
{
CompilerMessage( msg );
}
extern "C" int yywrap(void) {
return 1;
}
////////////////////////////////////////////////////////////////////////////////
// ¸â¹ö ÇÔ¼ö
SNode::SNode( int line, eSyntaxType type, SNode * pNode1, SNode * pNode2, SNode * pNode3 )
: m_iLine( line ), m_eType( type ), m_SymbolID( 0 ), m_eReturnType( T_VOID )
{
m_ArrPtrChilds[0] = pNode1;
m_ArrPtrChilds[1] = pNode2;
m_ArrPtrChilds[2] = pNode3;
}
const char * SyntaxTypeName[] =
{
"TYPE_STATEMENT_LIST",
"TYPE_EMPTY_STATEMENT",
"TYPE_ERROR_STATEMENT",
"TYPE_EXPRESSION",
"TYPE_IF_STATEMENT",
"TYPE_IF_ELSE_STATEMENT",
"TYPE_SWITCH_STATEMENT",
"TYPE_SWITCH_CASES",
"TYPE_CASE_ONE",
"TYPE_DEFAULT",
"TYPE_FOR_STATEMENT",
"TYPE_WHILE_STATEMENT",
"TYPE_FOR_EXPRESSION",
"TYPE_BREAK_STATEMENT",
"TYPE_CONTINUE_STATEMENT",
"TYPE_RETURN_STATEMENT",
"TYPE_DECLARATION",
"TYPE_SPECIFIER_VOID",
"TYPE_SPECIFIER_INT",
"TYPE_SPECIFIER_FLOAT",
"TYPE_SPECIFIER_BOOL",
"TYPE_SPECIFIER_STRING",
"TYPE_VARIABLE",
"TYPE_DECLARATOR_LIST",
"TYPE_INIT_DECLARATION",
"TYPE_NORMAL_DECLARATION",
"TYPE_ARRAY_INITIALIZE",
"TYPE_ARRAY_INITIALIZE2",
"TYPE_ARRAY_DECLARATION",
"TYPE_FUNCTION_DECLARATION",
"TYPE_INITIALIZER_LIST",
"TYPE_ARGUMENT_DECLARATION_LIST",
"TYPE_ARGUMENT_DECLARATION",
"TYPE_FUNCTION_DEFINITION",
"TYPE_CONSTANT_EXPRESSION",
"TYPE_EXPRESSION_LIST",
"TYPE_ASSIGNMENT_EXPESSION",
"TYPE_OR_EXPRESSION",
"TYPE_AND_EXPRESSION",
"TYPE_NOT_EXPRESSION",
"TYPE_EQUALITY_EXPRESSION",
"TYPE_NOTEQAUL_EXPRESSION",
"TYPE_LESSTHAN_EXPRESSION",
"TYPE_MORETHAN_EXPRESSION",
"TYPE_LESSTHANOREQUAL_EXPRESSION",
"TYPE_MORETHANOREQUAL_EXPRESSION",
"TYPE_ADDITION_EXPRESSION",
"TYPE_SUBTRACTION_EXPRESSION",
"TYPE_MULTIPLICATION_EXPRESSION",
"TYPE_DIVISION_EXPRESSION",
"TYPE_REMINDER_EXPRESSION",
"TYPE_COMPOUND_ADDITION",
"TYPE_COMPOUND_SUBTRACTION",
"TYPE_COMPOUND_MULTIPLICATION",
"TYPE_COMPOUND_DIVISION",
"TYPE_COMPOUND_REMINDER",
"TYPE_PREFIXINCREMENT",
"TYPE_PREFIXDECREMENT",
"TYPE_ARRAY_INDEXING",
"TYPE_FUNCTION_CALL",
"TYPE_POSTFIXINCREMENT",
"TYPE_POSTFIXDECREMENT"
};
void SNode::Show( int level, MESSAGE_FUNCTION2 Print, CSymbolTable * pSymbolTable )
{
const char * DataTypeString[] = { "void", "bool", "int", "float", "string" };
int nl = level;
if (!this) return;
if( m_eType != TYPE_STATEMENT_LIST )
{
Print( itoa( m_iLine, szBuffer, 10 ) );
Print( ": " );
for ( int i = 0; i < level; i++ )
Print( " " );
Print( SyntaxTypeName[m_eType] );
switch( m_eType )
{
case TYPE_CONSTANT_EXPRESSION :
Print( " ( " );
Print( pSymbolTable->GetNameOfConst( m_SymbolID ) );
Print( " : " );
Print( DataTypeString[ pSymbolTable->GetTypeOfConst( m_SymbolID ) ] );
Print( " )" );
break;
case TYPE_INIT_DECLARATION :
case TYPE_NORMAL_DECLARATION :
case TYPE_ARRAY_INITIALIZE :
case TYPE_ARRAY_INITIALIZE2 :
case TYPE_ARRAY_DECLARATION :
case TYPE_ARGUMENT_DECLARATION :
case TYPE_VARIABLE :
case TYPE_PREFIXINCREMENT :
case TYPE_PREFIXDECREMENT :
case TYPE_POSTFIXINCREMENT :
case TYPE_POSTFIXDECREMENT :
case TYPE_COMPOUND_ADDITION :
case TYPE_COMPOUND_SUBTRACTION :
case TYPE_COMPOUND_MULTIPLICATION :
case TYPE_COMPOUND_DIVISION :
case TYPE_COMPOUND_REMINDER :
Print( " ( " );
Print( pSymbolTable->GetNameOfVar( m_SymbolID ) );
Print( " : " );
Print( DataTypeString[ pSymbolTable->GetTypeOfVar( m_SymbolID ) ] );
Print( " )" );
break;
}
nl++;
Print("\n");
}
for( int i = 0; m_ArrPtrChilds[i] != 0 && i < 3; i++ )
m_ArrPtrChilds[i]->Show( nl, Print, pSymbolTable );
}
bool SNode::SemanticCheck( CSymbolTable * pSymbolTable )
{
static eDataType tempType, tempType2;
switch( m_eType )
{
case TYPE_ARRAY_INDEXING :
//ù¹øÂ° intÀ϶§¸¸ À¯È¿Çϰí, ½Éº¼ÀÇ Å¸ÀÔ¿¡ ÀÇÇØ ŸÀÔÀÌ °áÁ¤µÊ.
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
else
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
break;
case TYPE_EXPRESSION :
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
break;
case TYPE_ARRAY_DECLARATION :
//ù¹øÂ° Â÷Àϵ尡 intÀ϶§¸¸ À¯È¿Çϰí, ½Éº¼ ŸÀÔ¿¡ ÀÇÇØ ŸÀÔÀÌ °áÁ¤µÊ.
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
else
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
break;
case TYPE_ARRAY_INITIALIZE2 :
//½Éº¼ ŸÀÔ°ú µÎ¹øÀç Â÷ÀϵåÀÇ Å¸ÀÔÀÌ °°ÀºÁö °Ë»çÇÏ°í °°À» ¶§ ½Éº¼ ŸÀÔÀ» ¸®ÅÏ
//ù¹øÂ° Â÷Àϵå´Â intÇüÀ̾î¾ß ÇÔ.
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
if( m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
break;
case TYPE_ARRAY_INITIALIZE :
//½Éº¼ ŸÀÔ°ú ù¹øÂ° Â÷ÀϵåÀÇ Å¸ÀÔÀÌ °°¾Æ¾ß ÇÔ.
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
return false;
break;
case TYPE_INIT_DECLARATION :
case TYPE_ASSIGNMENT_EXPRESSION :
//½Éº¼ ŸÀÔ°ú ù¹øÂ° Â÷ÀϵåÀÇ Å¸ÀÔÀÌ °°ÀºÁö °Ë»çÇÏ°í °°À» ¶§ ½Éº¼ ŸÀÔÀ» ¸®ÅÏ
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_eReturnType == T_VOID )
return false;
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
if( m_eReturnType != T_STRING )
return false;
}
break;
case TYPE_INITIALIZER_LIST :
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType == T_STRING )
{
if( m_ArrPtrChilds[1]->m_eReturnType == T_VOID )
return false;
}
else if( m_ArrPtrChilds[1]->m_eReturnType == T_STRING )
{
if( m_eReturnType == T_VOID )
return false;
m_eReturnType = T_STRING;
}
else
{
if( m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
break;
}
break;
case TYPE_DECLARATOR_LIST :
//ù¹øÂ° Â÷Àϵå¿Í µÎ¹øÂ° Â÷ÀϵåÀÇ Å¸ÀÔÀÌ °°ÀºÁö °Ë»çÇÏ°í °°À» ¶§ ù¹øÂ° Â÷Àϵå ŸÀÔ ¸®ÅÏ
if( m_ArrPtrChilds[0]->m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
else
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
break;
case TYPE_ADDITION_EXPRESSION :
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType == T_STRING )
{
if( m_ArrPtrChilds[1]->m_eReturnType == T_VOID )
return false;
}
else if( m_ArrPtrChilds[1]->m_eReturnType == T_STRING )
{
if( m_eReturnType == T_VOID )
return false;
m_eReturnType = T_STRING;
}
else
{
if( m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
}
break;
case TYPE_SUBTRACTION_EXPRESSION :
case TYPE_MULTIPLICATION_EXPRESSION :
case TYPE_DIVISION_EXPRESSION :
//ù¹øÂ° Â÷Àϵå¿Í µÎ¹øÂ° Â÷Àϵ尡 ´Ù¸¦ ¶§´Â ¹«È¿, int³ª floatÇüÀÌ ¾Æ´Ò °æ¿ì¿¡µµ ¹«È¿
if( m_ArrPtrChilds[0]->m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
{
return false;
}
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT )
return false;
break;
case TYPE_REMINDER_EXPRESSION :
//ù¹øÂ° Â÷Àϵå¿Í µÎ¹øÂ° Â÷Àϵ尡 ´Ù¸¦ ¶§´Â ¹«È¿, intÇüÀÌ ¾Æ´Ò °æ¿ì¿¡µµ ¹«È¿
if( m_ArrPtrChilds[0]->m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
{
return false;
break;
}
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType != T_INT )
return false;
break;
case TYPE_PREFIXINCREMENT :
case TYPE_PREFIXDECREMENT :
case TYPE_POSTFIXINCREMENT :
case TYPE_POSTFIXDECREMENT :
//int¿Í floatÇüÀÌ ¾Æ´Ñ °æ¿ì¿¡´Â ¹«È¿.
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT )
return false;
break;
case TYPE_NORMAL_DECLARATION :
case TYPE_CONSTANT_EXPRESSION :
case TYPE_VARIABLE :
//½Éº¼ÀÇ Å¸ÀÔÀÌ ÀÌ ³ëµåÀÇ Å¸ÀÔÀ» °áÁ¤
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
break;
case TYPE_NOT_EXPRESSION :
//ù¹øÂ° Â÷Àϵ尡 BOOLÇüÀÏ °æ¿ì¿¡¸¸ À¯È¿ÇÔ.
if( m_ArrPtrChilds[0]->m_eReturnType != T_BOOL )
return false;
else
m_eReturnType = T_BOOL;
break;
case TYPE_OR_EXPRESSION :
case TYPE_AND_EXPRESSION :
//ù¹øÂ° Â÷Àϵå¿Í µÎ¹øÂ° Â÷Àϵ尡 ¸ðµÎ boolÇüÀÏ ¶§¿¡¸¸ À¯È¿ÇÔ.
m_eReturnType = T_BOOL;
if( m_ArrPtrChilds[0]->m_eReturnType != T_BOOL || m_ArrPtrChilds[1]->m_eReturnType != T_BOOL )
{
return false;
}
break;
case TYPE_EQUALITY_EXPRESSION :
case TYPE_NOTEQAUL_EXPRESSION :
//¿ÞÂʰú ¿À¸¥ÂÊÀÇ Å¸ÀÔÀÌ °°¾Æ¾ß Çϸç, void´Â Çã¿ë ¾ÈµÊ.
tempType = m_ArrPtrChilds[0]->m_eReturnType;
if( tempType != m_ArrPtrChilds[1]->m_eReturnType || tempType == T_VOID )
return false;
else
m_eReturnType = T_BOOL;
break;
case TYPE_LESSTHAN_EXPRESSION :
case TYPE_MORETHAN_EXPRESSION :
case TYPE_LESSTHANOREQUAL_EXPRESSION :
case TYPE_MORETHANOREQUAL_EXPRESSION :
tempType = m_ArrPtrChilds[0]->m_eReturnType;
//ù ¹øÂ° Â÷Àϵå¿Í µÎ ¹øÂ° Â÷Àϵ尡 ´Ù¸¦ ¶§´Â ¹«È¿, int, floatÇüÀÌ ¾Æ´Ò °æ¿ì¿¡µµ ¿À·ù
if( tempType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
if( tempType != T_INT && tempType != T_FLOAT )
return false;
m_eReturnType = T_BOOL;
break;
case TYPE_COMPOUND_ADDITION :
//½Éº¼ÀÇ Å¸ÀÔÀÌ ÀÌ ³ëµåÀÇ Å¸ÀÔÀ» °áÁ¤
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
//int³ª float, stringÇüÀÌ ¾Æ´Ò °æ¿ì ¹«È¿
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT && m_eReturnType != T_STRING )
return false;
//½Éº¼ ŸÀÔ°ú ù¹øÂ° Â÷Àϵ尡 ´Ù¸¦ ¶§´Â ½Éº¼ ŸÀÔÀÌ stringÀÏ °æ¿ì¿¡¸¸ À¯È¿
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
if( m_eReturnType != T_STRING )
return false;
else
{
if( m_ArrPtrChilds[0]->m_eReturnType == T_VOID )
return false;
}
}
break;
case TYPE_COMPOUND_SUBTRACTION :
case TYPE_COMPOUND_MULTIPLICATION :
case TYPE_COMPOUND_DIVISION :
//½Éº¼ÀÇ Å¸ÀÔÀÌ ÀÌ ³ëµåÀÇ Å¸ÀÔÀ» °áÁ¤
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
//½Éº¼ ŸÀÔ°ú ù¹øÂ° Â÷Àϵ尡 ´Ù¸¦ ¶§´Â ¹«È¿, int³ª floatÇüÀÌ ¾Æ´Ò °æ¿ì¿¡µµ ¹«È¿
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
return false;
}
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT )
return false;
break;
case TYPE_COMPOUND_REMINDER :
//½Éº¼ÀÇ Å¸ÀÔÀÌ ÀÌ ³ëµåÀÇ Å¸ÀÔÀ» °áÁ¤
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
//½Éº¼ ŸÀÔ°ú ù¹øÂ° Â÷Àϵ尡 ´Ù¸¦ ¶§´Â ¹«È¿, intÇüÀÌ ¾Æ´Ò °æ¿ì¿¡µµ ¹«È¿
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
return false;
}
if( m_eReturnType != T_INT )
return false;
break;
case TYPE_FUNCTION_CALL :
{
SFuncType type = pSymbolTable->GetTypeOfFunc( m_SymbolID );
m_eReturnType = type.GetReturnType();
break;
}
case TYPE_SWITCH_STATEMENT :
{
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
m_eReturnType = T_VOID;
break;
}
case TYPE_CASE_ONE :
{
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
m_eReturnType = T_VOID;
break;
}
default :
m_eReturnType = T_VOID;
break;
}
return true;
}
CSyntaxTree::CSyntaxTree()
: m_pRoot( 0 )
, m_pSymbolTable( new CSymbolTable )
, m_pPtrStorage( new PTRSTORAGE )
{
}
CSyntaxTree::~CSyntaxTree()
{
Destroy();
delete m_pSymbolTable;
delete m_pPtrStorage;
}
void CSyntaxTree::Create( const char * szFileName )
{
FILE * fp = fopen( szFileName, "rt" );
if( fp == NULL )
return;
yylloc.first_line = 1;
Create( fp );
}
void CSyntaxTree::Create( FILE * fp )
{
yyin = fp;
g_pSynTree = this;
g_pSymbolTable = m_pSymbolTable;
g_pSymbolTable->Create();
yylloc.first_line = 1;
yyparse();
}
void CSyntaxTree::Destroy()
{
typedef PTRSTORAGE::iterator ITERATOR;
for( ITERATOR i = m_pPtrStorage->begin(); i != m_pPtrStorage->end(); i++ )
{
delete (*i);
}
m_pPtrStorage->clear();
m_pSymbolTable->Destroy();
}
int CSyntaxTree::Insert( int line, eSyntaxType SynType, int childID1, int childID2, int childID3 )
{
SNode * pNode = new SNode( line, SynType, (SNode*)childID1, (SNode*)childID2, (SNode*)childID3 );
assert( m_pPtrStorage->insert( pNode ).second );
if( pNode->SemanticCheck( m_pSymbolTable ) == false )
ErrorMessage( pNode->m_iLine, "ŸÀÔÀÌ ¸ÂÁö ¾Ê½À´Ï´Ù~\n" );
return (int)pNode;
}
int CSyntaxTree::Insert( int line, int symbolID, eSyntaxType SynType, int childID1, int childID2, int childID3 )
{
SNode * pNode = new SNode( line, SynType, (SNode*)childID1, (SNode*)childID2, (SNode*)childID3 );
assert( m_pPtrStorage->insert( pNode ).second );
pNode->m_SymbolID = symbolID;
if( pNode->SemanticCheck( m_pSymbolTable ) == false )
CompilerMessage2( "Error(line %d) : ŸÀÔÀÌ ¸ÂÁö ¾Ê½À´Ï´Ù~\n", pNode->m_iLine );
return (int)pNode;
}
void CSyntaxTree::SetRoot( int nodeID )
{
if( nodeID != 0 )
{
if( m_pRoot != NULL )
{
Destroy();
}
m_pRoot = (SNode*)nodeID;
}
}
void CSyntaxTree::Show( MESSAGE_FUNCTION2 Print )
{
if( m_pRoot != NULL )
{
m_pRoot->Show( 0, Print, m_pSymbolTable );
}
}