From d303447dc7a830489828be2e66ccf8c36af4aed6 Mon Sep 17 00:00:00 2001 From: Frederick Yin Date: Mon, 29 Aug 2022 22:59:56 +0800 Subject: hackc: backslash escape extension --- projects/hackc/__main__.py | 13 ++++++++++--- projects/hackc/parser.py | 5 +++-- projects/hackc/tokens.py | 8 ++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) (limited to 'projects/hackc') diff --git a/projects/hackc/__main__.py b/projects/hackc/__main__.py index a7bc06f..1cb5c3f 100644 --- a/projects/hackc/__main__.py +++ b/projects/hackc/__main__.py @@ -4,7 +4,7 @@ import os from .parser import Parser -def compile_jack(input_path: Path, verbose: bool): +def compile_jack(input_path: Path, extensions: list, verbose: bool): try: filenames = os.listdir(input_path) files = [Path(input_path / f) for f in filenames] @@ -16,7 +16,7 @@ def compile_jack(input_path: Path, verbose: bool): return for input_fn in jack_files: - parser = Parser(input_fn) + parser = Parser(input_fn, extensions=extensions) parser.tokenize() parser.print_tokens() @@ -24,6 +24,13 @@ def compile_jack(input_path: Path, verbose: bool): if __name__ == "__main__": parser = ArgumentParser("hackc") parser.add_argument("-v", "--verbose", action="store_true", help="verbose mode") + parser.add_argument( + "-E", + "--extension", + metavar="extension", + action="append", + help="enable extension of standard Jack", + ) parser.add_argument("input_path", help="Jack file or directory") args = parser.parse_args() - compile_jack(Path(args.input_path), args.verbose) + compile_jack(Path(args.input_path), args.extension or [], args.verbose) diff --git a/projects/hackc/parser.py b/projects/hackc/parser.py index 400b096..f73c3d1 100644 --- a/projects/hackc/parser.py +++ b/projects/hackc/parser.py @@ -29,8 +29,9 @@ SYMBOLS = "{}()[].,;+-*/&|<>=~" class Parser: - def __init__(self, fp): + def __init__(self, fp, extensions=[]): self._fp = fp + self._extensions = extensions self.tokens = [] def print_tokens(self): @@ -80,7 +81,7 @@ class Parser: break rem = line[pos:] # remainder of line - token = Token.from_line(rem, line_no, pos) + token = Token.from_line(rem, line_no, pos, extensions=self._extensions) if token is not None: self.tokens.append(token) pos += token.length() diff --git a/projects/hackc/tokens.py b/projects/hackc/tokens.py index 7ae37ce..50c4173 100644 --- a/projects/hackc/tokens.py +++ b/projects/hackc/tokens.py @@ -35,7 +35,7 @@ class Token: self.column = column @classmethod - def from_line(cls, line: str, line_no: int, column: int): + def from_line(cls, line: str, line_no: int, column: int, extensions=[]): """Extract first token from line and return it as an instance of Token.""" if not line: return None @@ -47,7 +47,11 @@ class Token: if int_match is not None: return Token("integer", int_match.group(1), line_no, column) - str_match = re.match('(".*")', line) + if "escape" in extensions: + str_match = re.match(r'("(.|\\")+?[^\\]")', line) + else: + str_match = re.match('(".*?")', line) + if str_match is not None: return Token("string", str_match.group(1), line_no, column) -- cgit v1.2.3