rdx.cpp |
int calculate_postfix(const std::vector<std::string> &postfix) { ... else if (is_fnamch(token[0])) { // 식별자라면 값을 가져와서 푸시 if (Table::instance()->exist(token) == false) throw Exception("Undefined identifier; define it first"); IdentifierInfo info = Table::instance()->get(token); std::string ival = info.value(); value = strtoi(ival); paramStack.push(value); ... } |
tbl 모듈은 식별자가 표에 존재하는지 확인하고 있으면 참을 반환하는 exist 메서드가 추가되었다.
Table.h |
... // 식별자 표에 식별자가 등록되어있는지 확인합니다. bool exist(const std::string &identifier) const; ... |
dcl 모듈은 main_dcl 함수가 수정되었다. 그리고 공통적으로 각각의 모듈에 대응하는 헤더 파일이 생성되었다.
dcl.h |
#ifndef __DECLARATION_H__ #define __DECLARATION_H__ #include <vector> #include "IdentifierInfo.h" // 선언을 분석하고 획득한 토큰의 벡터를 반환합니다. std::vector<IdentifierInfo> get_dcl_info(const char *decl); #endif |
rdx.h |
#ifndef __READ_EXPRESSION_H__ #define __READ_EXPRESSION_H__ // 식을 계산하고 값을 정수로 반환합니다. int calculate(const char *expr); #endif |
그리고 다음이 필자가 구현한, 선언 분석 모듈과 수식 분석 모듈이 결합된 프로그램이다.
main.cpp |
#include <iostream>
#include "common.h" #include "StringBuffer.h" #include "Table.h" #include "dcl.h" #include "rdx.h" #include "IdentifierInfo.h"
const int MAX_INPUT_SIZ = 256; static char input[MAX_INPUT_SIZ];
int main(void) { try { std::string command; std::string identifier, value; std::cout << "Usage: " << std::endl; std::cout << "- decl <declaration>" << std::endl; std::cout << "- movl <identifier> <value>" << std::endl; std::cout << "- calc <expression>" << std::endl; std::cout << "- exit" << std::endl;
while (true) { clear_input_buffer(); std::cout << "> "; std::cin >> command; if (command == "decl") { std::cin.ignore(1); std::cin.getline(input, MAX_INPUT_SIZ); std::vector<IdentifierInfo> decl_list = get_dcl_info(input); for (int i = 0, len = decl_list.size(); i < len; ++i) { const IdentifierInfo &info = decl_list[i]; Table::instance()->set(info.name(), info); } } else if (command == "movl") { std::cin >> identifier >> value; if (Table::instance()->exist(identifier) == false) { std::cout << "undefined identifier; define it first" << std::endl; continue; } IdentifierInfo &info = Table::instance()->get(identifier); info.set_value(value); } else if (command == "calc") { std::cin.ignore(1); std::cin.getline(input, MAX_INPUT_SIZ); try { std::cout << calculate(input) << std::endl; } catch (Exception &ex) { std::cout << ex.c_str() << std::endl; } } else if (command == "exit") { break; } else { std::cout << "unknown command; try again" << std::endl; } } return 0; } catch (Exception &ex) { std::cerr << ex.c_str() << std::endl; return 1; } } |
이와 같이 컴파일러를 만들기 위해 선언 분석 모듈과 수식 분석 모듈을 결합할 수 있었다.