Commit ffb4eaa1 authored by eckhart's avatar eckhart
Browse files

parse.py: bugfix Grammar.associated_symbols

parent fcc5e534
......@@ -131,7 +131,8 @@ class ParserError(Exception):
self.frozen_callstack = tuple() # type: Tuple[CallItem, ...] # tag_name, location
def __str__(self):
return "%i: %s %s" % (self.node.pos, str(self.rest[:25]), repr(self.node))
return "%i: %s %s (%s)" \
% (self.node.pos, str(self.rest[:25]), repr(self.node), str(self.error))
ResumeList = List[Union[RxPatternType, str, Callable]] # list of strings or regular expressions
......@@ -1123,6 +1124,7 @@ class Grammar:
def __init__(self, root: Parser = None, static_analysis: Optional[bool] = None) -> None:
"""Constructor of class Grammar.
:param root: If not None, this is goind to be the root parser of the grammar.
This allows to first construct an ensemble of parser objects and then
link those objects in a grammar-object, rather than adding the parsers
......@@ -1162,6 +1164,8 @@ class Grammar:
# during testing and development this does not need to be the case.)
if root:
self.root_parser__ = copy.deepcopy(root)
if not self.root_parser__.pname:
self.root_parser__.pname = "root"
self.static_analysis_pending__ = [True] # type: List[bool]
self.static_analysis_errors__ = [] # type: List[AnalysisError]
else:
......@@ -1185,10 +1189,14 @@ class Grammar:
while self.static_analysis_errors__:
self.static_analysis_errors__.pop()
self.static_analysis_errors__.extend(result)
has_errors = any(is_error(tpl[-1].code) for tpl in result)
if has_errors:
raise GrammarError(result)
self.static_analysis_pending__.pop()
# raise a GrammarError even if result only contains warnings.
# It is up to the caller to decide whether to ignore warnings
# # has_errors = any(is_error(tpl[-1].code) for tpl in result)
# # if has_errors
if result:
raise GrammarError(result)
def __str__(self):
return self.__class__.__name__
......@@ -2110,7 +2118,7 @@ class OneOrMore(UnaryParser):
>>> Grammar(sentence)('Wo viel der Weisheit, da auch viel des Grämens.').content
'Wo viel der Weisheit, da auch viel des Grämens.'
>>> str(Grammar(sentence)('.')) # an empty sentence also matches
' <<< Error on "." | Parser "{/\\\\w+,?/ ~}+ `.` ~" did not match! >>> '
' <<< Error on "." | Parser "root = {/\\\\w+,?/ ~}+ `.` ~" did not match! >>> '
>>> forever = OneOrMore(RegExp(''))
>>> Grammar(forever)('') # infinite loops will automatically be broken
Node(':EMPTY', '')
......@@ -2415,7 +2423,7 @@ class Series(MandatoryNary):
>>> Grammar(variable_name)('variable_1').content
'variable_1'
>>> str(Grammar(variable_name)('1_variable'))
' <<< Error on "1_variable" | Parser "/(?!\\\\d)\\\\w/ /\\\\w*/ ~" did not match! >>> '
' <<< Error on "1_variable" | Parser "root = /(?!\\\\d)\\\\w/ /\\\\w*/ ~" did not match! >>> '
EBNF-Notation: ``... ...`` (sequence of parsers separated by a blank or new line)
......
......@@ -33,7 +33,7 @@ from DHParser.toolkit import compile_python_object, re
from DHParser.log import is_logging, log_ST, log_parsing_history, start_logging
from DHParser.error import Error, is_error, adjust_error_locations, MANDATORY_CONTINUATION, \
MALFORMED_ERROR_STRING, MANDATORY_CONTINUATION_AT_EOF, RESUME_NOTICE, PARSER_STOPPED_BEFORE_END, \
PARSER_NEVER_TOUCHES_DOCUMENT
PARSER_NEVER_TOUCHES_DOCUMENT, CAPTURE_DROPPED_CONTENT_WARNING
from DHParser.parse import ParserError, Parser, Grammar, Forward, TKN, ZeroOrMore, RE, \
RegExp, Lookbehind, NegativeLookahead, OneOrMore, Series, Alternative, \
Interleave, CombinedParser, Text, EMPTY_NODE, Capture, Drop, Whitespace, \
......@@ -765,14 +765,16 @@ class TestPopRetrieve:
def test_capture_assertions(self):
try:
_ = Grammar(Capture(Drop(Whitespace(r'\s*'))))
assert False, "GrammarError expected!"
assert False, "GrammarError expected"
except GrammarError as ge:
pass
assert ge.errors and ge.errors[0][-1].code == CAPTURE_DROPPED_CONTENT_WARNING, \
"Capture-dropped-content-Warning expected"
try:
_ = Grammar(Capture(Series(Text(' '), Drop(Whitespace(r'\s*')))))
assert False, "ValueError expected!"
except GrammarError:
pass
assert False, "GrammarError expected"
except GrammarError as ge:
assert ge.errors and ge.errors[0][-1].code == CAPTURE_DROPPED_CONTENT_WARNING, \
"Capture-dropped-content-Warning expected"
cp = Capture(RegExp(r'\w+'))
cp.pname = "capture"
_ = Grammar(cp)
......@@ -1524,10 +1526,11 @@ class TestStaticAnalysis:
def test_cannot_capture_dropped_content(self):
p = Capture(Drop(Whitespace(" ")))
try:
gr = Grammar(p)
_ = Grammar(p)
assert False, "GrammarError expected"
except GrammarError:
pass
except GrammarError as ge:
assert ge.errors and ge.errors[0][-1].code == CAPTURE_DROPPED_CONTENT_WARNING, \
"Capture-dropped-content-Warning expected"
def test_cyclical_ebnf_error(self):
doc = Text('proper'); doc.pname = "doc"
......
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