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