In January 2021 we will introduce a 10 GB quota for project repositories. Higher limits for individual projects will be available on request. Please see https://doku.lrz.de/display/PUBLIC/GitLab for more information.

Commit 56729685 authored by di68kap's avatar di68kap

- parser.py, syntax.py: bug concerning collection of errors fixed

parent f117b6de
......@@ -66,8 +66,8 @@ class Error:
return prefix + "%s: %s" % (self.level_str, self.message)
def __repr__(self):
return 'Error("%s", %i, %s, %i, %i, %i)' \
% (self.message, self.level, repr(self.code), self.pos, self.line, self.column)
return 'Error("%s", %s, %i, %i, %i)' \
% (self.message, repr(self.code), self.pos, self.line, self.column)
@property
def level_str(self):
......
......@@ -2039,7 +2039,7 @@ class Compiler:
else:
self._dirty_flag = True
result = self.compile(node)
self.propagate_error_flags(node)
self.propagate_error_flags(node, lazy=True)
return result
def set_grammar_name(self, grammar_name="", grammar_source=""):
......@@ -2058,12 +2058,13 @@ class Compiler:
self.grammar_source = load_if_file(grammar_source)
@staticmethod
def propagate_error_flags(node: Node) -> None:
if node.error_flag < Error.HIGHEST:
def propagate_error_flags(node: Node, lazy: bool = True) -> None:
# See test_parser.TestCompilerClass.test_propagate_error()..
if not lazy or node.error_flag < Error.HIGHEST:
for child in node.children:
Compiler.propagate_error_flags(child)
node.error_flag = max(node.error_flag, child.error_flag)
if node.error_flag >= Error.HIGHEST:
if lazy and node.error_flag >= Error.HIGHEST:
return
@staticmethod
......@@ -2164,6 +2165,7 @@ def compile_source(source: str,
syntax_tree.log(log_file_name + '.ast')
if not is_error(syntax_tree.error_flag):
result = compiler(syntax_tree)
# print(syntax_tree.as_sxpr())
messages.extend(syntax_tree.collect_errors(source_text))
syntax_tree.error_flag = max(syntax_tree.error_flag, efl)
return result, messages, syntax_tree
......@@ -398,21 +398,25 @@ class Node(collections.abc.Sized):
return []
def _collect_errors(self, lbreaks: List[int] = [], clear_errors=False) -> List[Error]:
if self.error_flag:
errors = self.errors
if lbreaks:
for err in errors:
err.pos = self.pos
err.line, err.column = line_col(lbreaks, err.pos)
if clear_errors:
self._errors = []
self.error_flag = 0
if self.children:
for child in self.children:
errors.extend(child._collect_errors(lbreaks, clear_errors))
return errors
errors = self.errors
if errors and lbreaks:
for err in errors:
err.pos = self.pos
err.line, err.column = line_col(lbreaks, err.pos)
if self.children:
for child in self.children:
errors.extend(child._collect_errors(lbreaks, clear_errors))
if clear_errors:
self._errors = []
self.error_flag = 0
else:
return []
if self._errors:
self.error_flag = max(err.code for err in self.errors)
if self.children:
max_child_error = max(child.error_flag for child in self.children)
self.error_flag = max(self.error_flag, max_child_error)
return errors
def _tree_repr(self, tab, open_fn, close_fn, data_fn=identity, density=0) -> str:
......@@ -482,6 +486,8 @@ class Node(collections.abc.Sized):
# s += " '(pos %i)" % node.pos
if src:
txt += " '(pos %i " % node.pos # + " %i %i)" % line_col(src, node.pos)
if node.error_flag:
txt += " HAS ERRORS"
if node.errors:
txt += " '(err '(%s))" % ' '.join(str(err).replace('"', r'\"')
for err in node.errors)
......
python.exe setup.py build_ext --inplace
python3.exe setup.py sdist bdist
\ No newline at end of file
......@@ -12,12 +12,15 @@ SCHREIBWEISE
ym-: Chart. Sangall. A 194.
impir-: v. ibi.
form. sing.:
gen.:
-ri : v. ibi. adde Annal. Plac. a. 1266 p. 516,21.
-iae : Chron. Fred. 2,33. p. 56,22. 2,35.
abl.:
-um : Chron. Fred. 2,15. 2,35sqq. capit. p. 43. confunditur c. imperitus : v. ibi.
form. sing.:
gen.:
-ri: v. ibi. adde Annal. Plac. a. 1266 p. 516,21.
-iae: Chron. Fred. 2,33. p. 56,22. 2,35.
abl.:
-um: Chron. Fred. 2,15. 2,35sqq. capit. p. 43.
confunditur c.:
imperitus: v. ibi.
BEDEUTUNG
......
......@@ -17,7 +17,7 @@ Artikel = [LZ]
[ArtikelKopf]
BedeutungsPosition
[VerweisPosition]
{ SubArtikel }
{ UnterArtikel }
ArtikelVerfasser
[LZ] DATEI_ENDE
......@@ -41,9 +41,9 @@ LemmaVariante = LAT_WORT_TEIL { "-" LAT_WORT_TEIL }
## GRAMMATIK-POSITION ##
GrammatikPosition = "GRAMMATIK" [LZ] Grammatik §ABS { GrammatikVariante §ABS }
GrammatikPosition = "GRAMMATIK" [LZ] §Grammatik ABS { GrammatikVariante §ABS }
Grammatik = §wortart ABS flexion [genus]
Grammatik = wortart §ABS flexion [genus]
wortart = "nomen" | "n."
| "verb" | "v."
......@@ -51,14 +51,16 @@ wortart = "nomen" | "n."
| "adjektiv" | "adj."
| "praeposition" | "praep."
flexion = FLEX { "," §FLEX }
flexion = deklination | konjugation
deklination = FLEX §"," FLEX
konjugation = FLEX
FLEX = /-?[a-z]+/~
genus = "maskulinum" | "m."
| "femininum" | "f."
| "neutrum" | "n."
GrammatikVariante = [wortart ABS] flexion [genus] DPP { Beleg }+
GrammatikVariante = [wortart ABS] flexion [genus] DPP { Beleg }+
......@@ -73,14 +75,32 @@ Etymologie = FREITEXT
#### ARTIKEL-KOPF ############################################################
ArtikelKopf = { SchreibweisenPosition | StrukturPosition
| GebrauchPosition | MetrikPosition | VerwechselungPosition }+
ArtikelKopf = < SchreibweisenPosition | StrukturPosition | GebrauchPosition
| MetrikPosition | VerwechselungPosition >
SchreibweisenPosition = "SCHREIBWEISE" [LZ] §SWTyp DPP [LZ]
SWVariante { ABS SWVariante} [LZ]
SWTyp = "script. fat-" | "script."
SWVariante = Schreibweise DPP Beleg
Schreibweise = ZEICHENFOLGE
## Schreibweisen-Position ##
# TODO: Ggf. noch zu ergänzen um: Zusatz, Mehrere Tyen innerhalb der Schreibweisen-Position.
SchreibweisenPosition = "SCHREIBWEISE" [LZ] { SWKategorie }+
SWKategorie = SWTyp DPP [LZ] §{SWUnterkategorie | SWVariante { ABS SWVariante }}+ [LZ]
SWUnterkategorie = SWUnterTyp DPP [LZ] §SWVariante { ABS SWVariante }+ [LZ]
SWTyp = scriptfat | scriptform | script | form | OFFEN
SWVariante = !KATEGORIENZEILE Schreibweise DPP Beleg
Schreibweise = ZEICHENFOLGE
scriptfat = "script." "fat-"
scriptform = "script. " "form"
script = "srcipt."
form = "form"
#### STRUKTUR-POSITION #######################################################
StrukturPosition = "STRUKTUR" [LZ] { STVariante }+
STVariante = "TODO"
......@@ -96,7 +116,16 @@ DeutscheBedeutung = SW_DEU /(?:(?![A-ZÄÖÜ][A-ZÄÖÜ]).)+/~
Belege = "BELEGE" [LZ] (EinBeleg | { "*" EinBeleg }) ABS
EinBeleg = { !([LZ] "*" | SCHLUESSELWORT) /\s*[^\n]*/~ [ZW] }+ [Zusatz]
Zusatz = "ZUSATZ" /\s*.*/
#### VERWEIS-POSITION #####################################################
VerweisPosition = "VERWEISE"
#### UNTER-ARTIKEL ########################################################
UnterArtikel = "UNTER-ARTIKEL"
#### AUTOR/AUTORIN ###########################################################
......@@ -171,6 +200,7 @@ RZS = /\s*?\n|$/ # Rückwärtiger Zeilensprung oder T
ZEILENSPRUNG = /[ \t]*\n/~
KOMMENTARZEILEN = { /[ \t]*\n?[ \t]*/ COMMENT__ } # echte Kommentarzeilen
KATEGORIENZEILE = /[^:\n]+[:][ \t]*\n/ # Kategorienzeilen enthalten genau einen Doppelpunkt am Ende der Zeile
DATEI_ENDE = !/./
NIEMALS = /(?!.)/
......
Warning: Rule "SW_GRIECH" is not connected to parser root "Artikel" !
Warning: Rule "VerweisZiel" is not connected to parser root "Artikel" !
Warning: Rule "DEU_WORT" is not connected to parser root "Artikel" !
Warning: Rule "DEU_GROSS" is not connected to parser root "Artikel" !
Warning: Rule "DEU_KLEIN" is not connected to parser root "Artikel" !
Warning: Rule "LAT_WORT" is not connected to parser root "Artikel" !
Warning: Rule "GROSSSCHRIFT" is not connected to parser root "Artikel" !
Warning: Rule "ZW" is not connected to parser root "Artikel" !
Warning: Rule "LÜCKE" is not connected to parser root "Artikel" !
Warning: Rule "LEERZEILE" is not connected to parser root "Artikel" !
Warning: Rule "RZS" is not connected to parser root "Artikel" !
Warning: Rule "KOMMENTARZEILEN" is not connected to parser root "Artikel" !
Warning: Rule "NIEMALS" is not connected to parser root "Artikel" !
line: 31, column: 49, Error: Missing definition for symbol 'LemmaWort'
line: 70, column: 22, Error: Missing definition for symbol 'LAT'
line: 70, column: 28, Error: Missing definition for symbol 'GRI'
line: 78, column: 66, Error: Missing definition for symbol 'GebrauchPosition'
line: 79, column: 23, Error: Missing definition for symbol 'MetrikPosition'
line: 79, column: 40, Error: Missing definition for symbol 'VerwechselungPosition'
line: 88, column: 20, Error: Missing definition for symbol 'SWUnterTyp'
line: 89, column: 61, Error: Missing definition for symbol 'OFFEN'
line: 142, column: 1, Warning: Rule "SW_GRIECH" is not connected to parser root "Artikel" !
line: 158, column: 20, Error: Missing definition for symbol 'Autor'
line: 158, column: 30, Error: Missing definition for symbol 'Werk'
line: 158, column: 39, Error: Missing definition for symbol 'Stelle'
line: 158, column: 51, Error: Missing definition for symbol 'Datierung'
line: 158, column: 67, Error: Missing definition for symbol 'Edition'
line: 162, column: 1, Warning: Rule "VerweisZiel" is not connected to parser root "Artikel" !
line: 173, column: 1, Warning: Rule "DEU_GROSS" is not connected to parser root "Artikel" !
line: 174, column: 1, Warning: Rule "DEU_KLEIN" is not connected to parser root "Artikel" !
line: 175, column: 1, Warning: Rule "LAT_WORT" is not connected to parser root "Artikel" !
line: 177, column: 1, Warning: Rule "GROSSSCHRIFT" is not connected to parser root "Artikel" !
line: 199, column: 1, Warning: Rule "RZS" is not connected to parser root "Artikel" !
line: 206, column: 1, Warning: Rule "NIEMALS" is not connected to parser root "Artikel" !
line: 208, column: 1, Warning: Rule "DUMMY" is not connected to parser root "Artikel" !
......@@ -27,8 +27,9 @@ sys.path.extend(['../', './'])
from DHParser.toolkit import is_logging, logging, compile_python_object
from DHParser.stringview import StringView
from DHParser.error import Error
from DHParser.syntaxtree import mock_syntax_tree
from DHParser.parser import compile_source, Retrieve, Grammar, Forward, Token, ZeroOrMore, RE, \
RegExp, Lookbehind, NegativeLookahead, OneOrMore, Series, Alternative, AllOf, SomeOf
RegExp, Lookbehind, NegativeLookahead, OneOrMore, Series, Alternative, AllOf, SomeOf, Compiler
from DHParser.ebnf import get_ebnf_grammar, get_ebnf_transformer, get_ebnf_compiler
from DHParser.dsl import grammar_provider, DHPARSER_IMPORTS
......@@ -542,6 +543,22 @@ class TestBorderlineCases:
assert not cst.error_flag
class TestCompilerClass:
def test_error_propagations(self):
tree = mock_syntax_tree('(A (B 1) (C (D (E 2) (F 3))))')
A = tree
B = next(tree.find(lambda node: str(node) == "1"))
D = next(tree.find(lambda node: node.parser.name == "D"))
F = next(tree.find(lambda node: str(node) == "3"))
B.add_error("Error in child node")
F.add_error("Error in child's child node")
Compiler.propagate_error_flags(tree, lazy=True)
assert A.error_flag
assert not D.error_flag
Compiler.propagate_error_flags(tree, lazy=False)
assert D.error_flag
if __name__ == "__main__":
from DHParser.testing import runner
with logging(False):
......
......@@ -23,6 +23,7 @@ import copy
import sys
sys.path.extend(['../', './'])
from DHParser.error import Error
from DHParser.syntaxtree import Node, mock_syntax_tree, TOKEN_PTYPE
from DHParser.transform import traverse, reduce_single_child, \
replace_by_single_child, flatten, remove_expendables
......@@ -124,6 +125,23 @@ class TestNode:
assert nd1.pos == 0, "Expected Node.pos == 0, got %i" % nd1.pos
assert nd2.pos == 3, "Expected Node.pos == 3, got %i" % nd2.pos
def test_collect_errors(self):
tree = mock_syntax_tree('(A (B 1) (C (D (E 2) (F 3))))')
A = tree
B = next(tree.find(lambda node: str(node) == "1"))
D = next(tree.find(lambda node: node.parser.name == "D"))
F = next(tree.find(lambda node: str(node) == "3"))
B.add_error("Error in child node")
F.add_error("Error in child's child node")
tree.error_flag = Error.ERROR
errors = tree.collect_errors()
assert len(errors) == 2, str(errors)
assert A.error_flag
assert D.error_flag
errors = tree.collect_errors(clear_errors=True)
assert len(errors) == 2
assert not D.error_flag
class TestErrorHandling:
def test_error_flag_propagation(self):
......
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