2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit f45d1378 authored by eckhart's avatar eckhart
Browse files

- parser.py: better parser history representation

parent dbe834e8
...@@ -138,27 +138,32 @@ class HistoryRecord: ...@@ -138,27 +138,32 @@ class HistoryRecord:
parser call, which ist either MATCH, FAIL (i.e. no match) parser call, which ist either MATCH, FAIL (i.e. no match)
or ERROR. or ERROR.
""" """
__slots__ = ('call_stack', 'node', 'remaining', 'line_col') __slots__ = ('call_stack', 'node', 'text', 'line_col')
MATCH = "MATCH" MATCH = "MATCH"
ERROR = "ERROR" ERROR = "ERROR"
FAIL = "FAIL" FAIL = "FAIL"
def __init__(self, call_stack: List['Parser'], node: Node, remaining: int) -> None: def __init__(self, call_stack: List['Parser'], node: Node, text: StringView) -> None:
# copy call stack, dropping uninformative Forward-Parsers # copy call stack, dropping uninformative Forward-Parsers
self.call_stack = [p for p in call_stack if p.ptype != ":Forward"] # type: List['Parser'] self.call_stack = [p for p in call_stack if p.ptype != ":Forward"] # type: List['Parser']
self.node = node # type: Node self.node = node # type: Node
self.remaining = remaining # type: int self.text = text # type: StringView
self.line_col = (1, 1) # type: Tuple[int, int] self.line_col = (1, 1) # type: Tuple[int, int]
if call_stack: if call_stack:
grammar = call_stack[-1].grammar grammar = call_stack[-1].grammar
document = grammar.document__ document = grammar.document__
lbreaks = grammar.document_lbreaks__ lbreaks = grammar.document_lbreaks__
self.line_col = line_col(lbreaks, len(document) - remaining) self.line_col = line_col(lbreaks, len(document) - len(text))
def __str__(self): def __str__(self):
return 'line %i, column %i: %s "%s"' % \ if self.node:
(self.line_col[0], self.line_col[1], self.stack, str(self.node)) excerpt = self.text[:len(self.node)]
else:
excerpt = str(self.text[:25]) + '...'
excerpt = excerpt.replace('\n', '\\n')
return '%5i, %5i, %s, %s, "%s"' % \
(self.line_col[0], self.line_col[1], self.stack, self.status, excerpt)
def err_msg(self) -> str: def err_msg(self) -> str:
return self.ERROR + ": " + "; ".join( return self.ERROR + ": " + "; ".join(
...@@ -173,12 +178,16 @@ class HistoryRecord: ...@@ -173,12 +178,16 @@ class HistoryRecord:
@property @property
def status(self) -> str: def status(self) -> str:
return self.FAIL if self.node is None else \ return self.FAIL if self.node is None else \
self.err_msg() if self.node.error_flag else self.MATCH # has_errors(self.node._errors) ('"%s"' % self.err_msg()) if self.node.error_flag else self.MATCH # has_errors(self.node._errors)
# @property
# def extent(self) -> slice:
# return (slice(-self.remaining - len(self.node), -self.remaining) if self.node
# else slice(-self.remaining, None))
@property @property
def extent(self) -> slice: def remaining(self) -> int:
return (slice(-self.remaining - len(self.node), -self.remaining) if self.node return len(self.text) - (len(self.node) if self.node else 0)
else slice(-self.remaining, None))
@staticmethod @staticmethod
def last_match(history: List['HistoryRecord']) -> Union['HistoryRecord', None]: def last_match(history: List['HistoryRecord']) -> Union['HistoryRecord', None]:
...@@ -276,7 +285,7 @@ def add_parser_guard(parser_func): ...@@ -276,7 +285,7 @@ def add_parser_guard(parser_func):
# don't track returning parsers except in case an error has occurred # don't track returning parsers except in case an error has occurred
remaining = len(rest) remaining = len(rest)
if grammar.moving_forward__ or (node and node.error_flag): # node._errors if grammar.moving_forward__ or (node and node.error_flag): # node._errors
record = HistoryRecord(grammar.call_stack__, node, remaining) record = HistoryRecord(grammar.call_stack__, node, text)
grammar.history__.append(record) grammar.history__.append(record)
# print(record.stack, record.status, rest[:20].replace('\n', '|')) # print(record.stack, record.status, rest[:20].replace('\n', '|'))
grammar.moving_forward__ = False grammar.moving_forward__ = False
...@@ -838,7 +847,7 @@ class Grammar: ...@@ -838,7 +847,7 @@ class Grammar:
for record in self.history__: for record in self.history__:
if record.node and record.node._pos < 0: if record.node and record.node._pos < 0:
record.node.pos = 0 record.node.pos = 0
record = HistoryRecord(self.call_stack__.copy(), stitches[-1], len(rest)) record = HistoryRecord(self.call_stack__.copy(), stitches[-1], rest)
self.history__.append(record) self.history__.append(record)
# stop history tracking when parser returned too early # stop history tracking when parser returned too early
self.history_tracking__ = False self.history_tracking__ = False
...@@ -896,11 +905,6 @@ class Grammar: ...@@ -896,11 +905,6 @@ class Grammar:
Writes a log of the parsing history of the most recently parsed Writes a log of the parsing history of the most recently parsed
document. document.
""" """
def prepare_line(record):
excerpt = self.document__.text.__getitem__(record.extent)[:25].replace('\n', '\\n')
excerpt = "'%s'" % excerpt if len(excerpt) < 25 else "'%s...'" % excerpt
return [item for item in (record.stack, record.status, excerpt) if item]
def write_log(history, log_name): def write_log(history, log_name):
path = os.path.join(log_dir(), log_name + "_parser.log") path = os.path.join(log_dir(), log_name + "_parser.log")
if os.path.exists(path): if os.path.exists(path):
...@@ -920,7 +924,7 @@ class Grammar: ...@@ -920,7 +924,7 @@ class Grammar:
log_file_name = log_file_name[:-4] log_file_name = log_file_name[:-4]
full_history, match_history, errors_only = [], [], [] full_history, match_history, errors_only = [], [], []
for record in self.history__: for record in self.history__:
line = "; ".join(prepare_line(record)) line = str(record)
full_history.append(line) full_history.append(line)
if record.node and record.node.parser.ptype != WHITESPACE_PTYPE: if record.node and record.node.parser.ptype != WHITESPACE_PTYPE:
match_history.append(line) match_history.append(line)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment