예제 #1
0
    def _unary(cls, tok: Token) -> Node:
        # unary = ("+" | "-") unary | primary
        if Tokenizer.equal(tok, "+"):
            return cls._unary(unwrap_optional(tok.next))

        if Tokenizer.equal(tok, "-"):
            return Node(NodeKind.ND_NEG, lhs=cls._unary(unwrap_optional(tok.next)))

        return cls._primary(tok)
예제 #2
0
    def _primary(cls, tok: Token) -> Node:
        # primary = "(" expr ")" | ident | num
        if Tokenizer.equal(tok, "("):
            node = cls._expr(unwrap_optional(tok.next))
            cls._rest = unwrap_optional(Tokenizer.skip(cls._rest, ")"))
            return node

        if tok.kind == TokenKind.TK_IDENT:
            node = Node(NodeKind.ND_VAR, name=cls._prog[tok.loc])
            cls._rest = unwrap_optional(tok.next)
            return node
        if tok.kind == TokenKind.TK_NUM:
            node = Node(NodeKind.ND_NUM, val=tok.val)
            cls._rest = unwrap_optional(tok.next)
            return node

        raise TokenError(tok, cls._prog, "expected an expression")
예제 #3
0
파일: __init__.py 프로젝트: algobot76/pycc
def main(argv):
    if len(argv) != 2:
        raise PyccError(f"{argv[0]} invalid number of arguments")

    prog = argv[1]
    tok: Token = Tokenizer.tokenize(prog)
    node = Parser.parse(tok, prog)
    Codegen.codegen(node)
예제 #4
0
 def _assign(cls, tok: Token) -> Node:
     # assign = equality ("=" assign)?
     node = cls._equality(tok)
     if Tokenizer.equal(cls._rest, "="):
         node = Node(
             NodeKind.ND_ASSIGN,
             lhs=node,
             rhs=cls._assign(unwrap_optional(cls._rest.next)),
         )
     return node
예제 #5
0
    def _mul(cls, tok: Token) -> Node:
        # mul = unary ("*" unary | "/" unary)*
        node = cls._unary(tok)

        while True:
            if Tokenizer.equal(cls._rest, "/"):
                node = Node(
                    NodeKind.ND_DIV,
                    lhs=node,
                    rhs=cls._unary(unwrap_optional(cls._rest.next)),
                )
                continue
            if Tokenizer.equal(cls._rest, "*"):
                node = Node(
                    NodeKind.ND_MUL,
                    lhs=node,
                    rhs=cls._unary(unwrap_optional(cls._rest.next)),
                )
                continue

            return node
예제 #6
0
    def _equality(cls, tok: Token) -> Node:
        # equality = relational ("==" relational | "!=" relational)*
        node = cls._relational(tok)

        while True:
            if Tokenizer.equal(cls._rest, "=="):
                node = Node(
                    NodeKind.ND_EQ,
                    lhs=node,
                    rhs=cls._relational(unwrap_optional(cls._rest.next)),
                )
                continue

            if Tokenizer.equal(cls._rest, "!="):
                node = Node(
                    NodeKind.ND_NE,
                    lhs=node,
                    rhs=cls._relational(unwrap_optional(cls._rest.next)),
                )
                continue

            return node
예제 #7
0
    def _add(cls, tok: Token) -> Node:
        # add = mul ("+" mul | "-" mul)*``
        node = cls._mul(tok)

        while True:
            if Tokenizer.equal(cls._rest, "+"):
                node = Node(
                    NodeKind.ND_ADD,
                    lhs=node,
                    rhs=cls._mul(unwrap_optional(cls._rest.next)),
                )
                continue

            if Tokenizer.equal(cls._rest, "-"):
                node = Node(
                    NodeKind.ND_SUB,
                    lhs=node,
                    rhs=cls._mul(unwrap_optional(cls._rest.next)),
                )
                continue

            return node
예제 #8
0
    def _relational(cls, tok: Token) -> Node:
        # relational = add ("<" add | "<=" add | ">" add | ">=" add)*
        node = cls._add(tok)

        while True:
            if Tokenizer.equal(cls._rest, "<"):
                node = Node(
                    NodeKind.ND_LT,
                    lhs=node,
                    rhs=cls._add(unwrap_optional(cls._rest.next)),
                )
                continue

            if Tokenizer.equal(cls._rest, "<="):
                node = Node(
                    NodeKind.ND_LE,
                    lhs=node,
                    rhs=cls._add(unwrap_optional(cls._rest.next)),
                )
                continue

            if Tokenizer.equal(cls._rest, ">"):
                node = Node(
                    NodeKind.ND_LT,
                    lhs=cls._add(unwrap_optional(cls._rest.next)),
                    rhs=node,
                )
                continue

            if Tokenizer.equal(cls._rest, ">="):
                node = Node(
                    NodeKind.ND_LE,
                    lhs=cls._add(unwrap_optional(cls._rest.next)),
                    rhs=node,
                )
                continue

            return node
예제 #9
0
 def _expr_stmt(cls, tok: Token) -> Node:
     # expr-stmt = expr ";"
     node = Node(NodeKind.ND_EXPR_STMT, lhs=cls._expr(tok))
     cls._rest = unwrap_optional(Tokenizer.skip(cls._rest, ";"))
     return node