PL λαβ
Lab 1.2b[최준혁]: 구문 분석기 본문
예시 코드(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