This repository has been archived by the owner on Jul 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Finish chapter 5: Add ast_printer and test thr created functions
- Loading branch information
1 parent
4c6913c
commit 06320e0
Showing
5 changed files
with
147 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from yaplox.expr import Binary, Expr, ExprVisitor, Grouping, Literal, Unary | ||
|
||
|
||
class AstPrinter(ExprVisitor): | ||
def print(self, expr: Expr) -> str: | ||
return expr.accept(self) | ||
|
||
def visit_grouping_expr(self, expr: Grouping): | ||
return self._parenthesize("group", expr.expression) | ||
|
||
def visit_literal_expr(self, expr: Literal): | ||
if expr.value is None: | ||
return "nil" | ||
return str(expr.value) | ||
|
||
def visit_unary_expr(self, expr: Unary): | ||
return self._parenthesize(expr.operator.lexeme, expr.right) | ||
|
||
def visit_binary_expr(self, expr: Binary): | ||
return self._parenthesize(expr.operator.lexeme, expr.left, expr.right) | ||
|
||
def _parenthesize(self, name: str, *args: Expr): | ||
expressions = ["(", name] | ||
|
||
for expr in args: | ||
expressions.append(" ") | ||
expressions.append(expr.accept(self)) | ||
|
||
expressions.append(")") | ||
|
||
return "".join(expressions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# This file has been auto-generated by tools/generate_ast.py | ||
# Do not edit this file by hand. Or do, but it will be overwritten | ||
|
||
from abc import ABC, abstractmethod | ||
from typing import Any | ||
|
||
from yaplox.token import Token | ||
|
||
|
||
class ExprVisitor(ABC): | ||
"""This class is used as an Vistor for the Expr class""" | ||
|
||
@abstractmethod | ||
def visit_binary_expr(self, expr: "Binary"): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def visit_grouping_expr(self, expr: "Grouping"): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def visit_literal_expr(self, expr: "Literal"): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def visit_unary_expr(self, expr: "Unary"): | ||
raise NotImplementedError | ||
|
||
|
||
class Expr(ABC): | ||
@abstractmethod | ||
def accept(self, visitor: ExprVisitor): | ||
raise NotImplementedError | ||
|
||
|
||
class Binary(Expr): | ||
def __init__(self, left: Expr, operator: Token, right: Expr): | ||
self.left = left | ||
self.operator = operator | ||
self.right = right | ||
|
||
def accept(self, visitor: ExprVisitor): | ||
""" Create a accept method that calls the visitor. """ | ||
return visitor.visit_binary_expr(self) | ||
|
||
|
||
class Grouping(Expr): | ||
def __init__(self, expression: Expr): | ||
self.expression = expression | ||
|
||
def accept(self, visitor: ExprVisitor): | ||
""" Create a accept method that calls the visitor. """ | ||
return visitor.visit_grouping_expr(self) | ||
|
||
|
||
class Literal(Expr): | ||
def __init__(self, value: Any): | ||
self.value = value | ||
|
||
def accept(self, visitor: ExprVisitor): | ||
""" Create a accept method that calls the visitor. """ | ||
return visitor.visit_literal_expr(self) | ||
|
||
|
||
class Unary(Expr): | ||
def __init__(self, operator: Token, right: Expr): | ||
self.operator = operator | ||
self.right = right | ||
|
||
def accept(self, visitor: ExprVisitor): | ||
""" Create a accept method that calls the visitor. """ | ||
return visitor.visit_unary_expr(self) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from yaplox import expr | ||
from yaplox.ast_printer import AstPrinter | ||
from yaplox.token import Token | ||
from yaplox.token_type import TokenType | ||
|
||
|
||
class TestAstPrinter: | ||
def test_astrinter(self): | ||
# This is the main/test function given in the chapter for the | ||
# ast_printer in chapter A (Not Very) pretty printer. | ||
# This code might be obsolete in the future, but it is a lot cleaner then | ||
# creating a main function to test our code. | ||
expression = expr.Binary( | ||
expr.Unary(Token(TokenType.MINUS, "-", None, 1), expr.Literal(123)), | ||
Token(TokenType.STAR, "*", None, 1), | ||
expr.Grouping(expr.Literal(45.67)), | ||
) | ||
|
||
result = AstPrinter().print(expression) | ||
assert result == "(* (- 123) (group 45.67))" | ||
|
||
def test_astrinter_nill(self): | ||
# Test a single edge case None | ||
expression = expr.Literal(None) | ||
|
||
result = AstPrinter().print(expression) | ||
assert result == "nil" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters