#include "SyntaxTree.h" #include "SymbolTable.h" #include "lex.h" #include #include /////////////////////////////////////////////////////////////////////////////// // Àü¿ªº¯¼ö CSyntaxTree * g_pSynTree = 0; CSymbolTable * g_pSymbolTable = 0; char szBuffer[1024]; /////////////////////////////////////////////////////////////////////////////// // 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 ); } }