from lexer import TokenType class Expr: def accept(self, visitor): raise Exception("needs to be implemented") class Literal: def __init__(self, value): self.value = value def accept(self, visitor): visitor.visitLiteral(self) def __str__(self): return f"{self.value}" class Type: def __init__(self, name): self.name = name def __str__(self): return self.name class Symbol: def __init__(self, name): self.name = name def accept(self, visitor): visitor.visitSymbol(self) def __str__(self): return f"'{self.name}" class List: def __init__(self, args): self.args = args def accept(self, visitor): visitor.visitNary(self) def __str__(self): return "(" + " ".join(f"{arg}" for arg in self.args) + ")" def parseExpression(token, prev, tokens): idx = 0 args = [] prev = token while tokens[idx].type_ != TokenType.CLOSE_PAREN: token = tokens[idx] inc = 1 if token.type_ == TokenType.OPEN_PAREN: expr, inc = parseExpression(token, prev, tokens[idx+1:]) args.append(expr) elif token.type_ in (TokenType.STRING, TokenType.TRUE, TokenType.FALSE, TokenType.INT, TokenType.FLOAT): expr, inc = parseLiteral(token, prev, tokens[idx+1:]) args.append(expr) elif token.type_ in (TokenType.INT_TYPE, TokenType.FLOAT_TYPE, TokenType.STRING_TYPE, TokenType.ANY_TYPE): expr, inc = parseType(token, prev, tokens[idx+1:]) args.append(expr) else: expr, inc = parseSymbol(token, prev, tokens[idx+1:]) args.append(expr) idx += inc prev = token return Expr.List(args), idx + 2 # parens def parseSymbol(token, prev, tokens): return Expr.Symbol(token.text), 1 def parseLiteral(token, prev, tokens): return Expr.Literal(token.value), 1 def parseType(token, prev, tokens): return Expr.Type(token.text), 1 def parse(tokens): idx = 0 prev = None exprs = [] while tokens[idx].type_ != TokenType.EOF: token = tokens[idx] counter = 1 if token.type_ == TokenType.OPEN_PAREN: expr, counter = parseExpression(token, prev, tokens[idx+1:]) exprs.append(expr) elif token.type_ in (TokenType.FALSE, TokenType.TRUE, TokenType.STRING, TokenType.INT, TokenType.FLOAT): lit, counter = parseLiteral(token, prev, tokens[idx+1:]) exprs.append(lit) elif token.type_ in (TokenType.INT_TYPE, TokenType.FLOAT_TYPE, TokenType.STRING_TYPE, TokenType.ANY_TYPE): typ, counter = parseType(token, prev, tokens[idx+1:]) exprs.append(typ) else: sym, counter = parseSymbol(token, prev, tokens[idx+1:]) exprs.append(sym) idx += counter prev = token return exprs