Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
9.2.2023: Due to updates GitLab will be unavailable for some minutes between 9:00 and 11:00.
Open sidebar
badw-it
DHParser
Commits
241311a8
Commit
241311a8
authored
Jan 08, 2019
by
di68kap
Browse files
- more preliminary work for variable curated error messages
parent
6815e2b6
Changes
4
Hide whitespace changes
Inline
Side-by-side
DHParser/ebnf.py
View file @
241311a8
...
...
@@ -834,30 +834,24 @@ class EBNFCompiler(Compiler):
check_argnum
(
2
)
symbol
=
key
[:
-
6
]
error_msgs
=
self
.
directives
[
'error'
].
get
(
symbol
,
[])
if
symbol
in
self
.
rules
:
self
.
tree
.
new_error
(
node
,
'Custom error message for symbol "%s"'
%
symbol
+
'must be defined before the symbol!'
)
parameter_error
=
'Directive "%s" requires message string or a a pair '
\
'(regular expression or search string, message string) as argument!'
# if symbol in self.rules:
# self.tree.new_error(node, 'Custom error message for symbol "%s"' % symbol
# + 'must be defined before the symbol!')
if
node
.
children
[
1
if
len
(
node
.
children
)
==
2
else
2
].
parser
.
name
!=
'literal'
:
self
.
tree
.
new_error
(
node
,
'Directive "%s" requires message string or a a pair '
%
key
+
'(regular expression or search string, message string) as argument!'
)
if
len
(
node
.
children
)
==
2
:
if
node
.
children
[
1
].
parser
.
name
!=
'literal'
:
self
.
tree
.
new_error
(
node
,
parameter_error
)
else
:
error_msgs
.
append
((
''
,
unrepr
(
node
.
children
[
1
].
content
)))
if
len
(
node
.
children
)
==
3
:
if
(
node
.
children
[
1
].
parser
.
name
not
in
(
'literal'
,
'regexp'
)
or
node
.
children
[
2
].
parser
.
name
!=
'literal'
):
self
.
tree
.
new_error
(
node
,
parameter_error
)
else
:
error_msgs
.
append
((
self
.
_gen_search_rule
(
node
.
children
[
1
]),
unrepr
(
node
.
children
[
2
].
content
)))
error_msgs
.
append
((
''
,
unrepr
(
node
.
children
[
1
].
content
)))
elif
len
(
node
.
children
)
==
3
:
rule
=
self
.
_gen_search_rule
(
node
.
children
[
1
])
error_msgs
.
append
((
rule
if
rule
else
unrepr
(
node
.
children
[
1
].
content
),
unrepr
(
node
.
children
[
2
].
content
)))
else
:
self
.
tree
.
new_error
(
node
,
'Directive "%s" allows at most two parameters'
%
key
)
self
.
directives
[
'error'
][
symbol
]
=
error_msgs
elif
key
.
endswith
(
'_resume'
):
# if not all(child.parser.name in ('literal', 'regexp') for child in node.children[1:]):
# self.tree.new_error(node, 'Directive "%s" accepts only regular expressions or '
# 'plain strings as arguments, but no symbols without '
# 'quotation marks!' % key)
symbol
=
key
[:
-
7
]
if
symbol
in
self
.
directives
[
'resume'
]:
self
.
tree
.
new_error
(
node
,
'Reentry conditions for "%s" have already been defined'
...
...
@@ -866,12 +860,7 @@ class EBNFCompiler(Compiler):
reentry_conditions
=
[]
# type: List[Union[unrepr, str]]
for
child
in
node
.
children
[
1
:]:
rule
=
self
.
_gen_search_rule
(
child
)
if
rule
:
reentry_conditions
.
append
(
rule
)
else
:
# child.parser.name == 'symbol'
if
child
.
content
not
in
self
.
symbols
:
self
.
symbols
[
child
.
content
]
=
node
reentry_conditions
.
append
(
unrepr
(
child
.
content
.
strip
()))
reentry_conditions
.
append
(
rule
if
rule
else
unrepr
(
child
.
content
.
strip
()))
self
.
directives
[
'resume'
][
symbol
]
=
reentry_conditions
else
:
...
...
@@ -932,6 +921,7 @@ class EBNFCompiler(Compiler):
current_symbol
=
next
(
reversed
(
self
.
rules
.
keys
()))
msgs
=
self
.
directives
[
'error'
].
get
(
current_symbol
,
[])
if
msgs
:
# use class field instead or direct representation of error messages!
custom_args
.
append
(
'err_msgs='
+
str
(
msgs
))
compiled
=
self
.
non_terminal
(
node
,
'Series'
,
custom_args
)
node
.
result
=
saved_result
...
...
DHParser/parse.py
View file @
241311a8
...
...
@@ -1423,7 +1423,7 @@ class Series(NaryOperator):
found
=
text_
[:
10
].
replace
(
'
\n
'
,
'
\\
n '
)
for
search
,
message
in
self
.
err_msgs
:
rxs
=
not
isinstance
(
search
,
str
)
if
rxs
and
search
.
match
(
text_
)
or
not
rxs
and
text_
.
startswith
(
search
):
if
rxs
and
text_
.
match
(
search
)
or
not
rxs
and
text_
.
startswith
(
search
):
msg
=
message
.
format
(
parser
.
repr
,
found
)
break
else
:
...
...
DHParser/toolkit.py
View file @
241311a8
...
...
@@ -183,8 +183,17 @@ class unrepr:
>>> unrepr("re.compile(r'abc+')")
re.compile(r'abc+')
"""
def
__init__
(
self
,
s
):
self
.
s
=
s
def
__init__
(
self
,
s
:
str
):
self
.
s
=
s
# type: str
def
__eq__
(
self
,
other
:
Union
[
'unrepr'
,
str
]):
if
isinstance
(
other
,
unrepr
):
return
self
.
s
==
other
.
s
elif
isinstance
(
other
,
str
):
return
self
.
s
==
other
else
:
raise
TypeError
(
'unrepr objects can only be compared with '
'other unrepr objects or strings!'
)
def
__str__
(
self
):
return
self
.
s
...
...
test/test_ebnf.py
View file @
241311a8
...
...
@@ -453,18 +453,18 @@ class TestCuratedErrors:
Cureted Errors replace existing errors with alternative
error codes and messages that are more helptful to the user.
"""
def
test_user_error_declaration
(
self
):
lang
=
"""
document = series | /.*/
series = "X" | head §"C" "D"
head = "A" "B"
@series_error = "a user defined error message"
"""
try
:
parser
=
grammar_provider
(
lang
)()
assert
False
,
"Error definition after symbol definition should fail!"
except
CompilationError
as
e
:
pass
#
def test_user_error_declaration(self):
#
lang = """
#
document = series | /.*/
#
series = "X" | head §"C" "D"
#
head = "A" "B"
#
@series_error = "a user defined error message"
#
"""
#
try:
#
parser = grammar_provider(lang)()
#
assert False, "Error definition after symbol definition should fail!"
#
except CompilationError as e:
#
pass
def
test_curated_mandatory_continuation
(
self
):
lang
=
"""
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment