PL λαβ

Lab 1.2b[최준혁]: 구문 분석기 본문

kos

Lab 1.2b[최준혁]: 구문 분석기

junhyeokk 2021. 4. 12. 22:03

예시 코드(www.lwh.jp/lisp/index.html)를 최대한 따라가면서 Token과 Input 클래스 형태로 변환해보려 했습니다. 다만 read_list 함수의 경우 read_expr과 번갈아가며 재귀적으로 호출되는 것을 예시 코드처럼 따라하려했으나, 제대로 동작하지 않아 조금 다른방식으로 시도해보다 실패한 상태입니다.

from data_mark2 import Type, Data, mksym, mkint, nil, nilp, cons
from enum import Enum

class Error(Enum):
    Error_OK = 0
    Error_Syntax = 1

class Token:
    def __init__(self, lexeme, location):
        self.lexeme = lexeme
        self.location = location

    def __getitem__(self, idx):
        return self.lexeme[idx]

    def match(self, another_token):
        return self.lexeme == another_token.lexeme

class Input():
    def __init__(self, input_str):  # lex 역할을 여기서 수행
        """string을 의미없는 공백들은 없애고 token(word, punctuation)들로 쪼갬 + syntax error 발생"""
        self.token_list = []
        for location, token_str in enumerate(input_str.split(' ')):
            self.token_list.append(Token(token_str.upper(), location))
        self.current_index = -1

    def nextToken(self):
        if len(self.token_list) <= self.current_index:
            return Error.Error_Syntax, None
        self.current_index += 1
        return Error.Error_OK, self.token_list[self.current_index]

def read_expr(input_class):
    """single object를 읽어서 에러 상태와 나머지 input에 대한 포인터 반환"""
    err, token = input_class.nextToken()
    if err != Error.Error_OK:
        return err, None

    if token[0] == '(':
        err, result = read_list(input_class, token)
        return err, result
    elif token[0] == ')':
        return Error.Error_Syntax, None
    else:
        err, result = parse_simple(input_class, token)
        return err, result

def parse_simple(input_class, token):  # parser
    """간단한 데이터(integers, symbols, NIL에 대해 처리"""
    if token.lexeme.isdecimal():
        return Error.Error_OK, mkint(int(token.lexeme))
    elif token.lexeme == "NIL":
        return Error.Error_OK, nil()
    else:
        return Error.Error_OK, mksym(token.lexeme)

def read_list(input_class, token):
    """improper lists와 pair에 대해 처리"""
    pass
    # depth = 1
    # result_list = []
    #
    # while True:
    #     err, token = input_class.nextToken()
    #     if err != Error.Error_OK:
    #         return err, None
    #
    #     if token[0] == ')':
    #         depth -= 1
    #     elif token[0] == '(':
    #         depth += 1
    #     else:
    #         result_list.append(parse_simple(input_class, token))
    #
    #     if depth == 0:
    #         break
    #
    # result_data = Data(Type.PAIR, (result_list[0], None))
    # for result in result_list[1:-1]:
    #     result_data = Data(Type.PAIR, (result_data, result))
    # result_data.value[2] = result_list[-1]
    #
    # return Error.Error_OK, result_data

if __name__ == "__main__":
    input_line = input("> ")
    while input_line:
        input_class = Input(input_line)
        err, result_data = read_expr(input_class)

        if err == Error.Error_OK:
            print(result_data)
        elif err == Error.Error_Syntax:
            print("Syntax error")

        input_line = input("> ")

# > 42
# 42
# > ( foo bar )
# (FOO BAR)
# > ( s ( t . u ) v . ( w . nil ) )
# (S (T . U) V W)
# > ( )
# NIL

'kos' 카테고리의 다른 글

Lab 2.1: 환경  (0) 2021.04.13
Lab 1.2b[박인철]: 구문 분석기  (0) 2021.04.13
Lab 1.2b[김예령]: 구문 분석기  (0) 2021.04.12
Lab 1.2a[최준혁]: 구문 분석기  (0) 2021.04.08
Lab 1.2a[박인철]: 구문 분석기  (0) 2021.04.08
Comments