1#!/usr/bin/env python
2
3"""parser.py - A JavaScript parser, currently with many bugs.
4
5See README.md for instructions.
6"""
7
8from . import parser_tables
9from .lexer import JSLexer
10
11
12# "type: ignore" because mypy can't see inside js_parser.parser_tables.
13class JSParser(parser_tables.Parser):  # type: ignore
14    def __init__(self, goal='Script', builder=None):
15        super().__init__(goal, builder)
16        self._goal = goal
17
18    def clone(self):
19        return JSParser(self._goal, self.methods)
20
21    def on_recover(self, error_code, lexer, stv):
22        """Check that ASI error recovery is really acceptable."""
23        if error_code == 'asi':
24            # ASI is allowed in three places:
25            # - at the end of the source text
26            # - before a close brace `}`
27            # - after a LineTerminator
28            # Hence the three-part if-condition below.
29            #
30            # The other quirks of ASI are implemented by massaging the syntax,
31            # in parse_esgrammar.py.
32            if not self.closed and stv.term != '}' and not lexer.saw_line_terminator():
33                lexer.throw("missing semicolon")
34        else:
35            # ASI is always allowed in this one state.
36            assert error_code == 'do_while_asi'
37
38
39def parse_Script(text):
40    lexer = JSLexer(JSParser('Script'))
41    lexer.write(text)
42    return lexer.close()
43