Commit 3478a3af authored by Eckhart Arnold's avatar Eckhart Arnold

subtle refactorings

parent 9af7ce39
......@@ -140,7 +140,14 @@ class Error:
@property
def severity(self):
"""Returns a string representation of the error level, e.g. "warning"."""
return "Warning" if is_warning(self.code) else "Error"
if self.code < Error.WARNING:
return "Notice"
elif self.code < Error.ERROR:
return "Warning"
elif self.code < Error.FATAL:
return "Error"
else:
return "Fatal"
def visualize(self, document: str) -> str:
"""Shows the line of the document and the position where the error
......
......@@ -73,6 +73,7 @@ __all__ = ('start_logging',
'clear_logs',
'NONE_TAG',
'NONE_NODE',
'freeze_callstack',
'HistoryRecord',
'log_ST',
'log_parsing_history')
......@@ -246,6 +247,11 @@ NONE_TAG = ":None"
NONE_NODE = FrozenNode(NONE_TAG, '')
def freeze_callstack(call_stack: List[Tuple[str, int]]) -> Tuple[Tuple[str, int], ...]:
"""Returns a frozen copy of the call stack."""
return tuple((tn, pos) for tn, pos in call_stack if tn != ":Forward")
class HistoryRecord:
"""
Stores debugging information about one completed step in the
......@@ -292,15 +298,17 @@ class HistoryRecord:
'</style>\n</head>\n<body>\n')
HTML_LEAD_OUT = '\n</body>\n</html>\n'
def __init__(self, call_stack: List[Tuple[str, int]],
def __init__(self, call_stack: Union[List[Tuple[str, int]], Tuple[Tuple[str, int], ...]],
node: Optional[Node],
text: StringView,
line_col: Tuple[int, int],
errors: List[Error] = []) -> None:
# copy call stack, dropping uninformative Forward-Parsers
# self.call_stack = call_stack # type: Tuple[Tuple[str, int],...]
self.call_stack = tuple((tn, pos) for tn, pos in call_stack
if tn != ":Forward") # type: Tuple[Tuple[str, int],...]
if isinstance(call_stack, tuple):
self.call_stack = call_stack # type: Tuple[Tuple[str, int],...]
else:
self.call_stack = freeze_callstack(call_stack)
self.node = NONE_NODE if node is None else node # type: Node
self.text = text # type: StringView
self.line_col = line_col # type: Tuple[int, int]
......
......@@ -73,6 +73,7 @@ __all__ = ('ParserError',
'Option',
'ZeroOrMore',
'OneOrMore',
'MandatoryNary',
'Series',
'Alternative',
'AllOf',
......@@ -1835,7 +1836,7 @@ MessagesType = List[Tuple[Union[str, Any], str]]
NO_MANDATORY = 1000
class MandatoryElementsParser(NaryParser):
class MandatoryNary(NaryParser):
r"""
Attributes:
mandatory: Number of the element starting at which the element
......@@ -1856,7 +1857,7 @@ class MandatoryElementsParser(NaryParser):
mandatory: int = NO_MANDATORY,
err_msgs: MessagesType = [],
skip: ResumeList = []) -> None:
super(MandatoryElementsParser, self).__init__(*parsers)
super(MandatoryNary, self).__init__(*parsers)
length = len(self.parsers)
if mandatory < 0:
mandatory += length
......@@ -1947,7 +1948,7 @@ class MandatoryElementsParser(NaryParser):
return error, err_node, text_[i:]
class Series(MandatoryElementsParser):
class Series(MandatoryNary):
r"""
Matches if each of a series of parsers matches exactly in the order of
the series.
......@@ -2119,7 +2120,7 @@ class Alternative(NaryParser):
return self
class AllOf(MandatoryElementsParser):
class AllOf(MandatoryNary):
"""
Matches if all elements of a list of parsers match. Each parser must
match exactly once. Other than in a sequence, the order in which
......
......@@ -29,7 +29,7 @@ from typing import Tuple, Optional, List, Iterable, Union
from DHParser.error import Error, line_col
from DHParser.stringview import StringView
from DHParser.syntaxtree import Node, REGEXP_PTYPE, TOKEN_PTYPE, WHITESPACE_PTYPE, ZOMBIE_TAG
from DHParser.log import HistoryRecord
from DHParser.log import freeze_callstack, HistoryRecord
from DHParser.parse import Grammar, Parser, ParserError, ParseFunc
__all__ = ('trace_history', 'all_descendants', 'set_tracer',
......@@ -52,30 +52,25 @@ def trace_history(self: Parser, text: StringView) -> Tuple[Optional[Node], Strin
if not nd.children and nd.tag_name != ZOMBIE_TAG)
text_ = pe.rest[l:]
lc = line_col(grammar.document_lbreaks__, pe.error.pos)
# grammar.history__.append(
# HistoryRecord(grammar.call_stack__, pe.node, text_, lc, [pe.error]))
target = text
if len(target) >= 10:
target = target[:7] + '...'
if pe.first_throw:
# resume notice
notice = Error('Resuming from parser "{}" with parser "{}" at point: {}'
.format(pe.node.tag_name, grammar.call_stack__[-1][0],
repr(target)),
grammar.document_length__ - len(text_), Error.RESUME_NOTICE)
else:
# skip notice
notice = Error('Skipping within parser {} to point {}'
.format(grammar.call_stack__[-1][0], repr(target)),
self._grammar.document_length__ - len(text_), Error.RESUME_NOTICE)
if grammar.resume_notices__:
target = text
if len(target) >= 10:
target = target[:7] + '...'
if pe.first_throw:
# resume notice
notice = Error('Resuming from parser "{}" with parser "{}" at point: {}'
.format(pe.node.tag_name, grammar.call_stack__[-1][0],
repr(target)),
grammar.document_length__ - len(text_), Error.RESUME_NOTICE)
else:
# skip notice
notice = Error('Skipping within parser {} to point {}'
.format(grammar.call_stack__[-1][0], repr(target)),
self._grammar.document_length__ - len(text_), Error.RESUME_NOTICE)
grammar.tree__.add_error(pe.node, notice)
errors.append(notice)
errors.append(notice)
grammar.history__.append(HistoryRecord(
grammar.call_stack__, pe.node, text_, lc, errors))
getattr(pe, 'frozen_callstack', grammar.call_stack__), pe.node, text_, lc, errors))
grammar.call_stack__.append(
((self.repr if self.tag_name in (REGEXP_PTYPE, TOKEN_PTYPE)
......@@ -85,8 +80,8 @@ def trace_history(self: Parser, text: StringView) -> Tuple[Optional[Node], Strin
try:
node, rest = self._parse(text) # <===== call to the actual parser!
except ParserError as pe:
grammar.call_stack__.pop()
if pe.first_throw:
pe.frozen_callstack = freeze_callstack(grammar.call_stack__)
grammar.most_recent_error__ = pe
if self == grammar.start_parser__:
fe = grammar.most_recent_error__
......@@ -95,6 +90,7 @@ def trace_history(self: Parser, text: StringView) -> Tuple[Optional[Node], Strin
nd = fe.node
grammar.history__.append(
HistoryRecord(grammar.call_stack__, nd, fe.rest[len(nd):], lc, [fe.error]))
grammar.call_stack__.pop()
raise pe
# Mind that memoized parser calls will not appear in the history record!
......@@ -110,7 +106,8 @@ def trace_history(self: Parser, text: StringView) -> Tuple[Optional[Node], Strin
record = HistoryRecord(grammar.call_stack__, nd, rest, lc, [])
cs_len = len(record.call_stack)
if (not grammar.history__ or lc != grammar.history__[-1].line_col
or record.call_stack != grammar.history__[-1].call_stack[:cs_len]):
or record.call_stack != grammar.history__[-1].call_stack[:cs_len]
or self == grammar.start_parser__):
grammar.history__.append(record)
grammar.moving_forward__ = False
......
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