Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
badw-it
DHParser
Commits
e7c82501
Commit
e7c82501
authored
Jan 17, 2019
by
di68kap
Browse files
- better testing support for mandatory lookaheads
parent
447927f6
Changes
4
Show whitespace changes
Inline
Side-by-side
DHParser/error.py
View file @
e7c82501
...
...
@@ -71,19 +71,20 @@ class Error:
# warning codes
REDEFINED_DIRECTIVE_WARNING
=
ErrorCode
(
1
0
1
)
REDECLARED_TOKEN_WARNING
=
ErrorCode
(
1
0
2
)
REDEFINED_DIRECTIVE_WARNING
=
ErrorCode
(
11
0
)
REDECLARED_TOKEN_WARNING
=
ErrorCode
(
12
0
)
UNDEFINED_SYMBOL_IN_TRANSFORMATION_TABLE
=
ErrorCode
(
6
0
1
)
UNDEFINED_SYMBOL_IN_TRANSFORMATION_TABLE
=
ErrorCode
(
61
0
)
# error codes
MANDATORY_CONTINUATION
=
ErrorCode
(
1001
)
PARSER_DID_NOT_MATCH
=
ErrorCode
(
1002
)
PARSER_LOOKAHEAD_MATCH_ONLY
=
ErrorCode
(
1003
)
PARSER_STOPPED_BEFORE_END
=
ErrorCode
(
1004
)
CAPTURE_STACK_NOT_EMPTY
=
ErrorCode
(
1005
)
MALFORMED_ERROR_STRING
=
ErrorCode
(
1006
)
MANDATORY_CONTINUATION
=
ErrorCode
(
1010
)
MANDATORY_CONTINUATION_AT_EOF
=
ErrorCode
(
1015
)
PARSER_DID_NOT_MATCH
=
ErrorCode
(
1020
)
PARSER_LOOKAHEAD_MATCH_ONLY
=
ErrorCode
(
1030
)
PARSER_STOPPED_BEFORE_END
=
ErrorCode
(
1040
)
CAPTURE_STACK_NOT_EMPTY
=
ErrorCode
(
1050
)
MALFORMED_ERROR_STRING
=
ErrorCode
(
1060
)
def
__init__
(
self
,
message
:
str
,
pos
,
code
:
ErrorCode
=
ERROR
,
orig_pos
:
int
=
-
1
,
line
:
int
=
-
1
,
column
:
int
=
-
1
)
->
None
:
...
...
@@ -102,7 +103,7 @@ class Error:
prefix
=
''
if
self
.
line
>
0
:
prefix
=
"%i:%i: "
%
(
max
(
self
.
line
,
0
),
max
(
self
.
column
,
0
))
return
prefix
+
"%s: %s"
%
(
self
.
severity
,
self
.
message
)
return
prefix
+
"%s
(%i)
: %s"
%
(
self
.
severity
,
self
.
code
,
self
.
message
)
def
__repr__
(
self
):
return
'Error("%s", %s, %i, %i, %i, %i)'
\
...
...
DHParser/parse.py
View file @
e7c82501
...
...
@@ -1434,7 +1434,9 @@ class Series(NaryOperator):
self
.
grammar
.
tree__
.
add_error
(
node
,
error
)
else
:
msg
=
'%s expected, "%s" found!'
%
(
parser
.
repr
,
found
)
mandatory_violation
=
Error
(
msg
,
location
,
Error
.
MANDATORY_CONTINUATION
)
mandatory_violation
=
Error
(
msg
,
location
,
Error
.
MANDATORY_CONTINUATION
if
text_
else
Error
.
MANDATORY_CONTINUATION_AT_EOF
)
self
.
grammar
.
tree__
.
add_error
(
node
,
mandatory_violation
)
text_
=
text_
[
i
:]
results
+=
(
node
,)
...
...
DHParser/testing.py
View file @
e7c82501
...
...
@@ -334,16 +334,22 @@ def grammar_unit(test_unit, parser_factory, transformer_factory, report=True, ve
return
True
return
False
def
lookahead_artifact
(
raw_errors
):
def
lookahead_artifact
(
parser
,
raw_errors
):
"""
Returns True, if the error merely occured, because the parser
Returns True, if the error merely occur
r
ed, because the parser
stopped in front of a sequence that was captured by a lookahead
operator. This is required for testing of parsers that put a
lookahead operator at the end. See test_testing.TestLookahead.
operator or if a mandatory lookahead failed at the end of data.
This is required for testing of parsers that put a lookahead
operator at the end. See test_testing.TestLookahead.
"""
return
len
(
raw_errors
)
==
2
\
and
raw_errors
[
-
1
].
code
==
Error
.
PARSER_LOOKAHEAD_MATCH_ONLY
\
and
raw_errors
[
-
2
].
code
==
Error
.
PARSER_STOPPED_BEFORE_END
return
((
len
(
raw_errors
)
==
2
# case 1: superfluous data for lookahead
and
raw_errors
[
-
1
].
code
==
Error
.
PARSER_LOOKAHEAD_MATCH_ONLY
and
raw_errors
[
-
2
].
code
==
Error
.
PARSER_STOPPED_BEFORE_END
)
# case 2: mandatory lookahead failure at end of text
or
(
len
(
raw_errors
)
==
1
and
raw_errors
[
-
1
].
code
==
Error
.
MANDATORY_CONTINUATION_AT_EOF
)
and
any
(
isinstance
(
parser
,
Lookahead
)
for
parser
in
parser
.
history__
[
-
1
].
call_stack
))
for
parser_name
,
tests
in
test_unit
.
items
():
assert
parser_name
,
"Missing parser name in test %s!"
%
unit_name
...
...
@@ -374,7 +380,6 @@ def grammar_unit(test_unit, parser_factory, transformer_factory, report=True, ve
infostr
=
' match-test "'
+
test_name
+
'" ... '
errflag
=
len
(
errata
)
try
:
cst
=
parser
(
test_code
,
parser_name
,
track_history
=
has_lookahead
(
parser_name
))
except
UnknownParserError
as
upe
:
cst
=
RootNode
()
...
...
@@ -388,7 +393,7 @@ def grammar_unit(test_unit, parser_factory, transformer_factory, report=True, ve
tests
.
setdefault
(
'__ast__'
,
{})[
test_name
]
=
ast
# log_ST(ast, "match_%s_%s.ast" % (parser_name, clean_test_name))
raw_errors
=
cst
.
collect_errors
()
if
is_error
(
cst
.
error_flag
)
and
not
lookahead_artifact
(
raw_errors
):
if
is_error
(
cst
.
error_flag
)
and
not
lookahead_artifact
(
parser
,
raw_errors
):
errors
=
adjust_error_locations
(
raw_errors
,
test_code
)
errata
.
append
(
'Match test "%s" for parser "%s" failed:
\n\t
Expr.: %s
\n\n\t
%s
\n\n
'
%
(
test_name
,
parser_name
,
'
\n\t
'
.
join
(
test_code
.
split
(
'
\n
'
)),
...
...
@@ -430,7 +435,7 @@ def grammar_unit(test_unit, parser_factory, transformer_factory, report=True, ve
cst
=
RootNode
(
node
).
new_error
(
node
,
str
(
upe
))
errata
.
append
(
'Unknown parser "{}" in fail test "{}"!'
.
format
(
parser_name
,
test_name
))
tests
.
setdefault
(
'__err__'
,
{})[
test_name
]
=
errata
[
-
1
]
if
not
is_error
(
cst
.
error_flag
)
and
not
lookahead_artifact
(
cst
.
collect_errors
()):
if
not
is_error
(
cst
.
error_flag
)
and
not
lookahead_artifact
(
parser
,
cst
.
collect_errors
()):
errata
.
append
(
'Fail test "%s" for parser "%s" yields match instead of '
'expected failure!'
%
(
test_name
,
parser_name
))
tests
.
setdefault
(
'__err__'
,
{})[
test_name
]
=
errata
[
-
1
]
...
...
test/test_testing.py
View file @
e7c82501
...
...
@@ -253,7 +253,7 @@ class TestLookahead:
"""
EBNF
=
r
"""
document = { category | entry } { LF }
category = {LF } sequence_of_letters { /:/ sequence_of_letters } /:/ &(LF sequence_of_letters)
category = {LF } sequence_of_letters { /:/ sequence_of_letters } /:/
§
&(LF sequence_of_letters)
entry = { LF } sequence_of_letters !/:/
sequence_of_letters = /[A-Za-z0-9 ]+/
LF = / *\n/
...
...
@@ -263,7 +263,8 @@ class TestLookahead:
"category"
:
{
"match"
:
{
1
:
"""Mountains: big:
K2"""
K2"""
,
2
:
"""Rivers:"""
# allowed because lookahaead failure occurs at end of file and is mandatory!
},
"fail"
:
{
6
:
"""Mountains: big:"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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