Skip to content

Commit

Permalink
Parser (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
glorialeezero authored Nov 28, 2024
2 parents 63fdf0c + 6cad043 commit bed119c
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 7 deletions.
4 changes: 2 additions & 2 deletions qupsy/language.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def __str__(self) -> str:
return str(self.value)

def __repr__(self) -> str:
return f"{self.value}"
return f"Integer({self.value})"

@property
def cost(self) -> int:
Expand All @@ -89,7 +89,7 @@ def __str__(self) -> str:
return self.name

def __repr__(self) -> str:
return f"{self.name}"
return f"Var({self.name})"

@property
def cost(self) -> int:
Expand Down
156 changes: 151 additions & 5 deletions qupsy/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,20 @@
from plare.parser import Parser
from plare.token import Token

from qupsy.language import Cmd, HoleCmd, Pgm, SeqCmd
from qupsy.language import (
GATE_MAP,
Aexp,
Cmd,
ForCmd,
Gate,
GateCmd,
HoleAexp,
HoleCmd,
Integer,
Pgm,
SeqCmd,
Var,
)


class LPAREN(Token):
Expand All @@ -21,6 +34,10 @@ class COLON(Token):
pass


class COMMA(Token):
pass


class NEWLINE(Token):
pass

Expand All @@ -41,12 +58,30 @@ class HOLE(Token):
pass


class FOR(Token):
pass


class IN(Token):
pass


class RANGE(Token):
pass


class ID(Token):
def __init__(self, value: str, *, lineno: int, offset: int) -> None:
super().__init__(value, lineno=lineno, offset=offset)
self.value = value


class DIGIT(Token):
def __init__(self, value: str, *, lineno: int, offset: int) -> None:
super().__init__(value, lineno=lineno, offset=offset)
self.value = int(value)


class Tree:
pass

Expand All @@ -63,13 +98,33 @@ def parsed(self) -> Pgm:


class CmdTree(Tree, ABC):

@property
@abstractmethod
def parsed(self) -> Cmd:
pass


class GateCmdTree(CmdTree):
def __init__(self, gate: GateTree) -> None:
self.gate = gate.parsed

@property
def parsed(self) -> Cmd:
return GateCmd(self.gate)


class ForCmdTree(CmdTree):
def __init__(self, var: ID, start: AexpTree, end: AexpTree, body: CmdTree):
self.var = var.value
self.start = start.parsed
self.end = end.parsed
self.body = body.parsed

@property
def parsed(self) -> Cmd:
return ForCmd(self.var, self.start, self.end, self.body)


class HoleCmdTree(CmdTree):
@property
def parsed(self) -> Cmd:
Expand All @@ -86,6 +141,57 @@ def parsed(self) -> Cmd:
return SeqCmd(self.pre, self.post)


class GateTree(Tree):
def __init__(self, gate: ID, args: ListTree) -> None:
self.gate = GATE_MAP[gate.value]
self.args = args.parsed

@property
def parsed(self) -> Gate:
return self.gate(*self.args)


class AexpTree(Tree, ABC):
@property
@abstractmethod
def parsed(self) -> Aexp:
pass


class HoleAexpTree(AexpTree):
@property
def parsed(self) -> Aexp:
return HoleAexp()


class IntegerTree(AexpTree):
def __init__(self, value: DIGIT) -> None:
self.value = value.value

@property
def parsed(self) -> Aexp:
return Integer(self.value)


class VarTree(AexpTree):
def __init__(self, var: ID) -> None:
self.var = var.value

@property
def parsed(self) -> Aexp:
return Var(self.var)


class ListTree(Tree):
def __init__(self, head: AexpTree, tail: ListTree | None = None) -> None:
self.head = head.parsed
self.tail = tail.parsed if tail is not None else []

@property
def parsed(self) -> list[Aexp]:
return [self.head] + self.tail


class State:
def __init__(self) -> None:
self.indentation = [""]
Expand Down Expand Up @@ -159,12 +265,20 @@ def build_lexer() -> Lexer[State]:
(r"[ \t\n]*\Z", remaining_dedents),
(r"[ \t\n]*\n", "end_of_line"),
(r"[ \t]+", "line"),
#
# Keywords
(r"def", DEF),
(r"for", FOR),
(r"in", IN),
(r"range", RANGE),
# Punctuation
(r",", COMMA),
(r"\(", LPAREN),
(r"\)", RPAREN),
(r":", COLON),
(r"[a-zA-Z][a-zA-Z0-9_]*", ID),
# Identifiers
(r"[a-zA-Z][a-zA-Z0-9]*", ID),
# Literals
(r"0|([1-9][0-9]*)", DIGIT),
(r"_", HOLE),
],
"end_of_line": [
Expand Down Expand Up @@ -209,7 +323,39 @@ def build_parser() -> Parser[Tree]:
],
"cmd": [
([HOLE, NEWLINE], HoleCmdTree, []),
# TODO: ForCmdTree, GateCmdTree
(
[
FOR,
ID,
IN,
RANGE,
LPAREN,
"aexp",
COMMA,
"aexp",
RPAREN,
COLON,
NEWLINE,
INDENT,
"cmd_seq",
DEDENT,
],
ForCmdTree,
[1, 5, 7, 12],
),
(["gate", NEWLINE], GateCmdTree, [0]),
],
"gate": [
([ID, LPAREN, "aexp_list", RPAREN], GateTree, [0, 2]),
],
"aexp_list": [
(["aexp", COMMA, "aexp_list"], ListTree, [0, 2]),
(["aexp"], ListTree, [0]),
],
"aexp": [
([HOLE], HoleAexpTree, []),
([DIGIT], IntegerTree, [0]),
([ID], VarTree, [0]),
],
}
)
Expand Down

0 comments on commit bed119c

Please sign in to comment.