|
|
@@ -55,60 +55,68 @@ def InitLexer(s, arena): |
|
|
# common thing: word parser does not use arena OR aliases. But it needs to
|
|
|
# create a command parser.
|
|
|
|
|
|
class ParseContext(object):
|
|
|
"""Context shared between the mutually recursive Command and Word parsers.
|
|
|
|
|
|
def MakeParser(line_reader, arena, aliases):
|
|
|
"""Top level parser."""
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', arena)
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
w_parser = word_parse.WordParser(lx, line_reader)
|
|
|
c_parser = cmd_parse.CommandParser(w_parser, lx, line_reader, arena,
|
|
|
aliases=aliases)
|
|
|
return w_parser, c_parser
|
|
|
|
|
|
|
|
|
# TODO: We could reuse w_parser with Reset() each time. That's what the REPL
|
|
|
# does.
|
|
|
# But LineLexer and Lexer are also stateful! So that might not be worth it.
|
|
|
# Hm the REPL only does line_reader.Reset()?
|
|
|
#
|
|
|
# NOTE: It probably needs to take a VirtualLineReader for $PS1, $PS2, ...
|
|
|
# values.
|
|
|
def MakeParserForCompletion(code_str, arena):
|
|
|
"""Parser for partial lines."""
|
|
|
# NOTE: We don't need to use a arena here? Or we need a "scratch arena" that
|
|
|
# doesn't interfere with the rest of the program.
|
|
|
line_reader = reader.StringLineReader(code_str, arena)
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', arena) # AtEnd() is true
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
w_parser = word_parse.WordParser(lx, line_reader)
|
|
|
c_parser = cmd_parse.CommandParser(w_parser, lx, line_reader, arena)
|
|
|
return w_parser, c_parser
|
|
|
|
|
|
|
|
|
def MakeWordParserForHereDoc(line_reader, arena):
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', arena)
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
return word_parse.WordParser(lx, line_reader)
|
|
|
|
|
|
|
|
|
def MakeWordParserForPlugin(code_str, arena):
|
|
|
line_reader = reader.StringLineReader(code_str, arena)
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', arena)
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
return word_parse.WordParser(lx, line_reader)
|
|
|
|
|
|
|
|
|
def MakeParserForCommandSub(line_reader, lexer):
|
|
|
"""To parse command sub, we want a fresh word parser state.
|
|
|
|
|
|
It's a new instance based on same lexer and arena.
|
|
|
In constrast, STATE is stored in the CommandParser and WordParser instances.
|
|
|
"""
|
|
|
arena = line_reader.arena
|
|
|
w_parser = word_parse.WordParser(lexer, line_reader)
|
|
|
c_parser = cmd_parse.CommandParser(w_parser, lexer, line_reader, arena)
|
|
|
return c_parser
|
|
|
|
|
|
|
|
|
# Another parser instantiation:
|
|
|
# - For Array Literal in word_parse.py WordParser:
|
|
|
# w_parser = WordParser(self.lexer, self.line_reader)
|
|
|
def __init__(self, arena, aliases):
|
|
|
self.arena = arena
|
|
|
self.aliases = aliases
|
|
|
|
|
|
def MakeParser(self, line_reader):
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', self.arena)
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
w_parser = word_parse.WordParser(self, lx, line_reader)
|
|
|
c_parser = cmd_parse.CommandParser(self, w_parser, lx, line_reader, self.arena,
|
|
|
aliases=self.aliases)
|
|
|
return w_parser, c_parser
|
|
|
|
|
|
def MakeWordParserForHereDoc(self, line_reader):
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', self.arena)
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
return word_parse.WordParser(self, lx, line_reader)
|
|
|
|
|
|
def MakeParserForCommandSub(self, line_reader, lexer):
|
|
|
"""To parse command sub, we want a fresh word parser state.
|
|
|
|
|
|
It's a new instance based on same lexer and arena.
|
|
|
"""
|
|
|
w_parser = word_parse.WordParser(self, lexer, line_reader)
|
|
|
c_parser = cmd_parse.CommandParser(self, w_parser, lexer, line_reader,
|
|
|
self.arena)
|
|
|
return c_parser
|
|
|
|
|
|
def MakeWordParserForPlugin(self, code_str, arena):
|
|
|
"""FOr $PS1, etc.
|
|
|
|
|
|
NOTE: Uses its own arena! I think that does nothing though?
|
|
|
"""
|
|
|
line_reader = reader.StringLineReader(code_str, arena)
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', arena)
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
return word_parse.WordParser(self, lx, line_reader)
|
|
|
|
|
|
# TODO: We could reuse w_parser with ResetInputObjects() each time. That's
|
|
|
# what the REPL does.
|
|
|
#
|
|
|
# NOTE: It probably needs to take a VirtualLineReader for $PS1, $PS2, ...
|
|
|
# values.
|
|
|
def MakeParserForCompletion(self, code_str, arena):
|
|
|
"""Parser for partial lines.
|
|
|
|
|
|
NOTE: Uses its own arena!
|
|
|
"""
|
|
|
# NOTE: We don't need to use a arena here? Or we need a "scratch arena" that
|
|
|
# doesn't interfere with the rest of the program.
|
|
|
line_reader = reader.StringLineReader(code_str, arena)
|
|
|
line_lexer = lexer.LineLexer(match.MATCHER, '', arena) # AtEnd() is true
|
|
|
lx = lexer.Lexer(line_lexer, line_reader)
|
|
|
w_parser = word_parse.WordParser(self, lx, line_reader)
|
|
|
c_parser = cmd_parse.CommandParser(self, w_parser, lx, line_reader, arena)
|
|
|
return w_parser, c_parser
|
|
|
|
|
|
# Another parser instantiation:
|
|
|
# - For Array Literal in word_parse.py WordParser:
|
|
|
# w_parser = WordParser(self.lexer, self.line_reader)
|