Commit befa3611 authored by di68kap's avatar di68kap
Browse files

trace.py: new module for tracing debugger...

parent 5ad96481
......@@ -371,7 +371,7 @@ CONFIG_PRESET['debug_compiler'] = False
# Makes DHParser.dsl.grammar_provider() write generated Python code to
# the log-file (if logging is on) or to the console (if logging is off)
# Default value: False
# Default value: '' (empty string, i.e. no log)
CONFIG_PRESET['compiled_EBNF_log'] = ''
......
# logging.py - logging and debugging for DHParser
# log.py - logging and debugging for DHParser
#
# Copyright 2018 by Eckhart Arnold (arnold@badw.de)
# Bavarian Academy of Sciences an Humanities (badw.de)
......@@ -41,9 +41,12 @@ and abreviated parsing history.
Example::
from DHParser import compile_source, logging
from DHParser import compile_source, logging, set_config_value
start_logging("LOGS")
set_config_value('log_syntax_trees', {'cst', 'ast'})
set_config_value('history_tracking', True)
set_config_value('resume_notices', True)
result, errors, ast = compile_source(source, preprocessor, grammar,
transformer, compiler)
"""
......@@ -76,7 +79,7 @@ __all__ = ('start_logging',
#######################################################################
#
# logging context manager and logfile support
# basic logging functionality
#
#######################################################################
......@@ -518,4 +521,3 @@ def log_parsing_history(grammar, log_file_name: str = '', html: bool = True) ->
write_log([heading] + full_history[-LOG_TAIL_THRESHOLD:], log_file_name + '_full.tail')
return True
......@@ -46,7 +46,8 @@ from DHParser.toolkit import sane_parser_name, escape_control_characters, re, cy
RX_NEVER_MATCH, RxPatternType
__all__ = ('Parser',
__all__ = ('ParserError',
'Parser',
'UnknownParserError',
'GrammarErrorType',
'GrammarError',
......@@ -91,14 +92,11 @@ __all__ = ('Parser',
########################################################################
#
# Parser base class
# ParserError class
#
########################################################################
EMPTY_NODE = FrozenNode(':EMPTY__', '')
class ParserError(Exception):
"""
A `ParserError` is thrown for those parser errors that allow the
......@@ -107,8 +105,8 @@ class ParserError(Exception):
occurred, the parser guard can resume the parsing process.
Currently, the only case when a `ParserError` is thrown (and not some
different kind of error like `UnknownParserError`, is when a `Series`-
detects a missing mandatory element.
different kind of error like `UnknownParserError`) is when a `Series`-
or `AllOf`-parser detects a missing mandatory element.
"""
def __init__(self, node: Node, rest: StringView, error: Optional[Error], first_throw: bool):
self.node = node # type: Node
......@@ -203,6 +201,16 @@ def reentry_point(rest: StringView,
return closest_match
########################################################################
#
# Parser base class
#
########################################################################
EMPTY_NODE = FrozenNode(':EMPTY__', '')
ApplyFunc = Callable[['Parser'], None]
FlagFunc = Callable[[ApplyFunc, Set[ApplyFunc]], bool]
......@@ -497,7 +505,6 @@ class Parser:
# Does this make sense? Or should it be changed?
if history_tracking__:
# don't track returning parsers except in case an error has occurred
# remaining = len(rest)
if grammar.moving_forward__:
record = HistoryRecord(grammar.call_stack__, node, text,
grammar.line_col__(text))
......
......@@ -61,7 +61,7 @@ __all__ = ('WHITESPACE_PTYPE',
#######################################################################
#
# parser base and mock parsers
# parser-related definitions
#
#######################################################################
......@@ -73,6 +73,7 @@ LEAF_PTYPES = {WHITESPACE_PTYPE, TOKEN_PTYPE, REGEXP_PTYPE}
ZOMBIE_TAG = "ZOMBIE__"
#######################################################################
#
# syntaxtree nodes
......@@ -1714,4 +1715,4 @@ def parse_tree(xml_sxpr_json: str) -> Optional[Node]:
# if __name__ == "__main__":
# st = parse_sxpr("(alpha (beta (gamma i\nj\nk) (delta y)) (epsilon z))")
# print(st.as_sxpr())
# print(st.as_xml())
# print(st.as_xml())
\ No newline at end of file
# trace.py - tracing of the parsing process (for debugging)
#
# Copyright 2018 by Eckhart Arnold (arnold@badw.de)
# Bavarian Academy of Sciences an Humanities (badw.de)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
"""
Module ``trace`` provides trace-debugging functionality for the
parser. The tracers are added or removed via monkey patching to
all or some particular parsers of a grammar and trace the actions
of these parsers, making use of the `call_stack__`, `history__`
and `moving_forward__`-hooks in the Grammar object.
This allows for more flexible and at the same time more focused
tracing of the parsing process than the (older) parsing-history-
tracking-mechanism in the `parse` module, which will eventually
be superceded by tracing.
"""
from typing import Tuple, Optional
from DHParser.stringview import StringView
from DHParser.syntaxtree import Node, REGEXP_PTYPE, TOKEN_PTYPE
from DHParser.log import HistoryRecord
from DHParser.parse import ParserError
#######################################################################
#
# tracing of the parsing process
# (a light-weight alternative to full history recording)
#
#######################################################################
def parse_proxy(self, text: StringView) -> Tuple[Optional[Node], StringView]:
grammar = self._grammar
location = grammar.document_length__ - text._len
grammar.call_stack__.append(
((self.repr if self.tag_name in (REGEXP_PTYPE, TOKEN_PTYPE)
else (self.pname or self.tag_name)), location))
grammar.moving_forward__ = True
error = []
try:
node, text_ = self._proxied_parse_method(text)
except ParserError as pe:
error = [pe]
grammar.call_stack__.pop()
raise pe
# Mind that memoized parser calls will not appear in the history record!
# Don't track returning parsers except in case an error has occurred!
if grammar.moving_forward__ or error:
grammar.history__.append(HistoryRecord(
grammar.call_stack__, node, text, grammar.line_col__(text), error))
grammar.moving_forward__ = False
grammar.call_stack__.pop()
return node, text
Supports Markdown
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