Commit 6919c326 authored by di68kap's avatar di68kap
Browse files

- DHParser: parse.py: bugfix: Fehlermeldungen fehlten in History-Log

parent bf11f707
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -372,8 +372,8 @@ def log_ST(syntax_tree, log_file_name):
    """
    if is_logging():
        path = os.path.join(log_dir(), log_file_name)
        if os.path.exists(path):
            print('WARNING: Log-file "%s" already exists and will be overwritten!' % path)
        # if os.path.exists(path):
        #     print('WARNING: Log-file "%s" already exists and will be overwritten!' % path)
        with open(path, "w", encoding="utf-8") as f:
            f.write(syntax_tree.as_sxpr())

@@ -401,7 +401,7 @@ def log_parsing_history(grammar, log_file_name: str = '', html: bool = True) ->
        path = os.path.join(log_dir(), log_name + "_parser.log" + htm)
        if os.path.exists(path):
            os.remove(path)
            print('WARNING: Log-file "%s" already existed and was deleted.' % path)
            # print('WARNING: Log-file "%s" already existed and was deleted.' % path)
        if history:
            with open(path, "w", encoding="utf-8") as f:
                if html:
+40 −26
Original line number Diff line number Diff line
@@ -106,9 +106,10 @@ class ParserError(Exception):
    different kind of error like `UnknownParserError`, is when a `Series`-
    detects a missing mandatory element.
    """
    def __init__(self, node: Node, rest: StringView, first_throw: bool):
    def __init__(self, node: Node, rest: StringView, error: Optional[Error], first_throw: bool):
        self.node = node   # type: Node
        self.rest = rest   # type: StringView
        self.error = error # type: Optional[Error]
        self.first_throw = first_throw  # type: bool

    def __str__(self):
@@ -263,6 +264,15 @@ class Parser:
        the business intelligence that is common to all parsers. The actual parsing is
        done in the overridden method `_parse()`.
        """
        def get_error_node_id(error_node: Node, root_node: RootNode) -> int:
            if error_node:
                error_node_id = id(error_node)
                while error_node_id not in grammar.tree__.error_nodes and error_node.children:
                    error_node = error_node.result[-1]
                    error_node_id = id(error_node)
            else:
                error_node_id = 0

        grammar = self._grammar
        location = grammar.document_length__ - len(text)

@@ -291,15 +301,16 @@ class Parser:
                                                         (':RegExp', ':Token', ':DropToken')
                                            else self.tag_name)
                grammar.moving_forward__ = True
                error = None

            try:
                # PARSER CALL: run _parse() method
                node, rest = self._parse(text)
            except ParserError as error:
            except ParserError as pe:
                # does this play well with variable setting? add rollback clause here? tests needed...
                gap = len(text) - len(error.rest)
                gap = len(text) - len(pe.rest)
                rules = grammar.resume_rules__.get(self.pname, [])
                rest = error.rest[len(error.node):]
                rest = pe.rest[len(pe.node):]
                i = reentry_point(rest, rules)
                if i >= 0 or self == grammar.start_parser__:
                    # apply reentry-rule or catch error at root-parser
@@ -307,26 +318,28 @@ class Parser:
                        i = 1
                    nd = Node(ZOMBIE_TAG, rest[:i]).with_pos(location)
                    rest = rest[i:]
                    assert error.node.children or (not error.node.result)
                    if error.first_throw:
                        node = error.node
                    assert pe.node.children or (not pe.node.result)
                    if pe.first_throw:
                        node = pe.node
                        node.result = node.children + (nd,)
                    else:
                        # TODO: ggf. Fehlermeldung, die sagt, wo es weitergeht anfügen
                        # TODO: ggf. Fehlermeldung, die sagt, wo es weitergeht, anfügen;
                        #       dürfte allerdings erst an den nächsten(!) Knoten angehängt werden (wie?)
                        node = Node(self.tag_name,
                                    (Node(ZOMBIE_TAG, text[:gap]).with_pos(location),
                                     error.node, nd))
                elif error.first_throw:
                    raise ParserError(error.node, error.rest, first_throw=False)
                                     pe.node, nd))
                elif pe.first_throw:
                    raise ParserError(pe.node, pe.rest, pe.error, first_throw=False)
                else:
                    result = (Node(ZOMBIE_TAG, text[:gap]).with_pos(location), error.node) if gap \
                        else error.node  # type: ResultType
                    result = (Node(ZOMBIE_TAG, text[:gap]).with_pos(location), pe.node) if gap \
                        else pe.node  # type: ResultType
                    if grammar.tree__.errors[-1].code == Error.MANDATORY_CONTINUATION_AT_EOF:  # EXPERIMENTAL!!
                        node = error.node
                        node = pe.node
                    else:
                        raise ParserError(Node(self.tag_name, result).with_pos(location),
                                          text, first_throw=False)
                                          text, pe.error, first_throw=False)
                error = pe.error  # needed for history tracking


            if left_recursion_depth__:
                self.recursion_counter[location] -= 1
@@ -343,6 +356,7 @@ class Parser:
                                            "Refactor grammar to avoid slow parsing.",
                                            node.pos if node else location,
                                            Error.LEFT_RECURSION_WARNING))
                            error_id = id(node)
                            grammar.last_recursion_location__ = location
                    # don't overwrite any positive match (i.e. node not None) in the cache
                    # and don't add empty entries for parsers returning from left recursive calls!
@@ -372,12 +386,12 @@ class Parser:
                    record = HistoryRecord(grammar.call_stack__, node, text,
                                           grammar.line_col__(text))
                    grammar.history__.append(record)
                elif node:
                    nid = id(node)  # type: int
                    if nid in grammar.tree__.error_nodes:
                elif error:
                    # error_nid = id(node)  # type: int
                    # if error_nid in grammar.tree__.error_nodes:
                    record = HistoryRecord(grammar.call_stack__, node, text,
                                           grammar.line_col__(text),
                                               grammar.tree__.error_nodes[nid])
                                           [error])
                    grammar.history__.append(record)
                grammar.moving_forward__ = False
                grammar.call_stack__.pop()
@@ -1763,7 +1777,7 @@ class Series(NaryParser):
        ret_node = self._return_values(results)  # type: Node
        if error:
            raise ParserError(ret_node.with_pos(self.grammar.document_length__ - len(text)),
                              text, first_throw=True)
                              text, error, first_throw=True)
        return ret_node, text_

    def __repr__(self):
@@ -1980,7 +1994,7 @@ class AllOf(NaryParser):
        nd = self._return_values(results)  # type: Node
        if error:
            raise ParserError(nd.with_pos(self.grammar.document_length__ - len(text)),
                              text, first_throw=True)
                              text, error, first_throw=True)
        return nd, text_

    def __repr__(self):
+4 −2
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ import os
import sys

scriptdir = os.path.dirname(os.path.abspath(__file__))
i = scriptdir.find('DHParser')
i, k = scriptdir.find('DHParser-submodule'), len('DHParser-submodule')
if i < 0:
    i, k = scriptdir.find('DHParser'), len('DHParser')
if i >= 0:
    dhparserdir = scriptdir[:i + 8]
    dhparserdir = scriptdir[:i + k]
    sys.path.append(dhparserdir)
else:
    dhparserdir = ''
+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ class Node: # (collections.abc.Sized): Base class omitted for cython-compatibil
            S-Expression-output.
    """

    __slots__ = '_result', 'children', '_pos', 'tag_name', '_xml_attr', '_id'
    __slots__ = '_result', 'children', '_pos', 'tag_name', '_xml_attr'

    def __init__(self, tag_name: str, result: ResultType, leafhint: bool = False) -> None:
        """
+2 −2
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ from DHParser.stringview import StringView

class TestParserError:
    def test_parser_error_str(self):
        pe = ParserError(Node('TAG', 'test').with_pos(0), StringView('Beispiel'), True)
        pe = ParserError(Node('TAG', 'test').with_pos(0), StringView('Beispiel'), None, True)
        assert str(pe).find('Beispiel') >= 0 and str(pe).find('TAG') >= 0


@@ -779,7 +779,7 @@ class TestReentryAfterError:


class TestConfiguredErrorMessages:
    def test_(self):
    def test_configured_error_message(self):
        lang = """
            document = series | /.*/
            @series_error = "a badly configured error message {5}"
+4 −4

File changed.

Contains only whitespace changes.

Loading