Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
badw-it
DHParser
Commits
700c2983
Commit
700c2983
authored
Sep 17, 2017
by
Eckhart Arnold
Browse files
- syntaxtree.py: Node.error_flag now integer value indicating error level (use with care!)
parent
3c8c31d4
Changes
3
Hide whitespace changes
Inline
Side-by-side
DHParser/ebnf.py
View file @
700c2983
...
...
@@ -556,9 +556,9 @@ class EBNFCompiler(Compiler):
remove_connections
(
self
.
root_symbol
)
for
leftover
in
defined_symbols
:
self
.
rules
[
leftover
][
0
].
add_error
((
'Rule "%s" is not connected to parser '
'root "%s" !'
)
%
(
leftover
,
self
.
root_symbol
)
+
' (Use directive "@testing=True" '
'to supress this error message.)'
)
'root "%s" !'
)
%
(
leftover
,
self
.
root_symbol
)
+
' (Use directive "@testing=True" '
'to supress this error message.)'
)
# root_node.error_flag = True
# set root_symbol parser and assemble python grammar definition
...
...
@@ -587,7 +587,7 @@ class EBNFCompiler(Compiler):
else
:
assert
nd
.
parser
.
name
==
"directive"
,
nd
.
as_sxpr
()
self
.
compile
(
nd
)
node
.
error_flag
=
node
.
error_flag
or
nd
.
error_flag
node
.
error_flag
=
max
(
node
.
error_flag
,
nd
.
error_flag
)
self
.
definitions
.
update
(
definitions
)
return
self
.
assemble_parser
(
definitions
,
node
)
...
...
DHParser/parser.py
View file @
700c2983
...
...
@@ -76,7 +76,7 @@ except ImportError:
from
DHParser.toolkit
import
is_logging
,
log_dir
,
logfile_basename
,
escape_re
,
sane_parser_name
from
DHParser.syntaxtree
import
WHITESPACE_PTYPE
,
TOKEN_PTYPE
,
ZOMBIE_PARSER
,
ParserBase
,
\
Node
,
TransformationFunc
Error
,
is_error
,
Node
,
TransformationFunc
from
DHParser.toolkit
import
StringView
,
EMPTY_STRING_VIEW
,
sv_match
,
sv_index
,
sv_search
,
\
load_if_file
,
error_messages
,
line_col
...
...
@@ -1854,11 +1854,11 @@ class Compiler:
@
staticmethod
def
propagate_error_flags
(
node
:
Node
)
->
None
:
if
not
node
.
error_flag
:
if
node
.
error_flag
<
Error
.
HIGHEST
:
for
child
in
node
.
children
:
Compiler
.
propagate_error_flags
(
child
)
if
child
.
error_flag
:
node
.
error_flag
=
True
node
.
error_flag
=
max
(
node
.
error_flag
,
child
.
error_flag
)
if
node
.
error_flag
>
=
Error
.
HIGHEST
:
return
@
staticmethod
...
...
@@ -1945,18 +1945,17 @@ def compile_source(source: str,
syntax_tree
.
log
(
log_file_name
+
'.cst'
)
parser
.
log_parsing_history__
(
log_file_name
)
assert
syntax_tree
.
error_flag
or
str
(
syntax_tree
)
==
source_text
,
str
(
syntax_tree
)
assert
is_error
(
syntax_tree
.
error_flag
)
or
str
(
syntax_tree
)
==
source_text
,
str
(
syntax_tree
)
# only compile if there were no syntax errors, for otherwise it is
# likely that error list gets littered with compile error messages
result
=
None
if
syntax_tree
.
error_flag
:
if
is_error
(
syntax_tree
.
error_flag
)
:
errors
=
syntax_tree
.
collect_errors
()
else
:
transformer
(
syntax_tree
)
if
is_logging
():
syntax_tree
.
log
(
log_file_name
+
'.ast'
)
errors
=
syntax_tree
.
collect_errors
()
if
not
errors
:
if
not
is_error
(
syntax_tree
.
error_flag
):
result
=
compiler
(
syntax_tree
)
errors
=
syntax_tree
.
collect_errors
()
if
syntax_tree
.
error_flag
else
[]
errors
=
syntax_tree
.
collect_errors
()
messages
=
error_messages
(
source_text
,
errors
)
return
result
,
messages
,
syntax_tree
DHParser/syntaxtree.py
View file @
700c2983
...
...
@@ -40,6 +40,8 @@ __all__ = ('WHITESPACE_PTYPE',
'ZOMBIE_PARSER'
,
'ParserBase'
,
'Error'
,
'is_warning'
,
'is_error'
,
'Node'
,
'mock_syntax_tree'
,
'TransformationFunc'
)
...
...
@@ -124,14 +126,16 @@ ZOMBIE_PARSER = ZombieParser()
class
Error
:
__slots__
=
[
'message'
,
'
category
'
,
'code'
,
'pos'
,
'line'
,
'column'
]
__slots__
=
[
'message'
,
'
level
'
,
'code'
,
'pos'
,
'line'
,
'column'
]
ERROR
=
"error"
WARNING
=
"warning"
WARNING
=
1
ERROR
=
1000
HIGHEST
=
ERROR
def
__init__
(
self
,
message
:
str
,
category
:
str
=
''
,
code
:
str
=
''
):
def
__init__
(
self
,
message
:
str
,
level
:
int
=
ERROR
,
code
:
str
=
''
):
self
.
message
=
message
self
.
category
=
category
or
Error
.
ERROR
assert
level
>=
0
self
.
level
=
level
or
Error
.
ERROR
self
.
code
=
code
self
.
pos
=
-
1
self
.
line
=
-
1
...
...
@@ -139,14 +143,26 @@ class Error:
def
__str__
(
self
):
return
(
"line: %3i, column: %2i"
%
(
self
.
line
,
self
.
column
)
+
", %s: %s"
%
(
self
.
category
,
self
.
message
))
+
", %s: %s"
%
(
self
.
level_str
,
self
.
message
))
@
staticmethod
def
from_template
(
template
:
str
,
category
:
str
=
''
,
content
:
Union
[
tuple
,
dict
]
=
()):
def
from_template
(
template
:
str
,
level
:
int
=
ERROR
,
content
:
Union
[
tuple
,
dict
]
=
()):
if
isinstance
(
content
,
tuple
):
return
Error
(
template
%
content
,
category
,
template
)
return
Error
(
template
%
content
,
level
,
template
)
else
:
return
Error
(
template
.
format
(
**
content
),
category
,
template
)
return
Error
(
template
.
format
(
**
content
),
level
,
template
)
@
property
def
level_str
(
self
):
return
"warning"
if
is_warning
(
self
.
level
)
else
"error"
def
is_warning
(
level
):
return
level
<
Error
.
ERROR
def
is_error
(
level
):
return
level
>=
Error
.
ERROR
ChildrenType
=
Tuple
[
'Node'
,
...]
...
...
@@ -185,8 +201,9 @@ class Node(collections.abc.Sized):
example by calling ``isinstance(node.parer, ...)``.
errors (list): A list of parser- or compiler-errors:
tuple(position, string) attached to this node
error_flag (bool): True, if either the node or any of its
descendants has errors.
error_flag (int): 0 if no error occurred in either the node
itself or any of its descendants. Otherwise contains the
highest warning or error level or all errors that occurred.
len (int): The full length of the node's string result if the
node is a leaf node or, otherwise, the concatenated string
result's of its descendants. The figure always represents
...
...
@@ -217,7 +234,7 @@ class Node(collections.abc.Sized):
"""
# self._result = '' # type: StrictResultType
# self.children = () # type: ChildrenType
#
self.error_flag =
False
# type: bool
self
.
error_flag
=
0
# type: bool
self
.
_errors
=
[]
# type: List[Error]
self
.
result
=
result
self
.
_len
=
len
(
self
.
_result
)
if
not
self
.
children
else
\
...
...
@@ -287,7 +304,9 @@ class Node(collections.abc.Sized):
if
isinstance
(
result
,
StringView
)
else
result
or
''
# type: StrictResultType
self
.
children
=
cast
(
ChildrenType
,
self
.
_result
)
\
if
isinstance
(
self
.
_result
,
tuple
)
else
cast
(
ChildrenType
,
())
# type: ChildrenType
self
.
error_flag
=
any
(
r
.
error_flag
for
r
in
self
.
children
)
# type: bool
if
self
.
children
:
self
.
error_flag
=
max
(
self
.
error_flag
,
max
(
child
.
error_flag
for
child
in
self
.
children
))
# type: bool
@
property
def
pos
(
self
)
->
int
:
...
...
@@ -321,14 +340,14 @@ class Node(collections.abc.Sized):
def
add_error
(
self
:
'Node'
,
template
:
Union
[
str
,
Error
],
category
:
str
=
''
,
level
:
int
=
0
,
content
:
Union
[
tuple
,
dict
]
=
())
->
'Node'
:
if
isinstance
(
template
,
Error
):
assert
not
(
bool
(
category
)
or
bool
(
content
))
assert
not
(
bool
(
level
)
or
bool
(
content
))
self
.
_errors
.
append
(
template
)
else
:
self
.
_errors
.
append
(
Error
.
from_template
(
template
,
category
,
content
))
self
.
error_flag
=
True
self
.
_errors
.
append
(
Error
.
from_template
(
template
,
level
,
content
))
self
.
error_flag
=
max
(
self
.
error_flag
,
self
.
_errors
[
-
1
].
level
)
return
self
...
...
@@ -358,7 +377,7 @@ class Node(collections.abc.Sized):
errors
=
self
.
errors
if
clear_errors
:
self
.
_errors
=
[]
self
.
error_flag
=
False
self
.
error_flag
=
0
if
self
.
children
:
for
child
in
self
.
children
:
errors
.
extend
(
child
.
collect_errors
(
clear_errors
))
...
...
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