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
ee075c8b
Commit
ee075c8b
authored
Jun 22, 2017
by
Eckhart Arnold
Browse files
- enbf.py: added directive "@testing"
parent
feefd262
Changes
6
Hide whitespace changes
Inline
Side-by-side
DHParser/ebnf.py
View file @
ee075c8b
...
...
@@ -25,7 +25,7 @@ except ImportError:
import
re
from
typing
import
Callable
,
Dict
,
List
,
Set
,
Tuple
from
DHParser.toolkit
import
load_if_file
,
escape_re
,
md5
,
sane_parser_name
,
warnings
from
DHParser.toolkit
import
load_if_file
,
escape_re
,
md5
,
sane_parser_name
from
DHParser.parsers
import
Grammar
,
mixin_comment
,
nil_scanner
,
Forward
,
RE
,
NegativeLookahead
,
\
Alternative
,
Sequence
,
Optional
,
Required
,
OneOrMore
,
ZeroOrMore
,
Token
,
Compiler
,
\
ScannerFunc
...
...
@@ -329,8 +329,9 @@ class EBNFCompiler(Compiler):
self
.
directives
=
{
'whitespace'
:
self
.
WHITESPACE
[
'horizontal'
],
'comment'
:
''
,
'literalws'
:
[
'right'
],
'tokens'
:
set
(),
# alt. 'scanner_tokens'
'filter'
:
dict
()}
# alt. 'filter'
'tokens'
:
set
(),
# alt. 'scanner_tokens'
'filter'
:
dict
(),
# alt. 'filter'
'testing'
:
False
}
@
property
def
result
(
self
)
->
str
:
...
...
@@ -408,7 +409,7 @@ class EBNFCompiler(Compiler):
'r"""Parser for '
+
article
+
self
.
grammar_name
+
' source file'
+
(
', with this grammar:'
if
self
.
grammar_source
else
'.'
)]
definitions
.
append
((
'parser_initialization__'
,
'"upon instatiation"'
))
definitions
.
append
((
'parser_initialization__'
,
'"upon insta
n
tiation"'
))
if
self
.
grammar_source
:
definitions
.
append
((
'source_hash__'
,
'"%s"'
%
md5
(
self
.
grammar_source
,
__version__
)))
...
...
@@ -440,7 +441,7 @@ class EBNFCompiler(Compiler):
# check for unconnected rules
if
warnings
()
:
if
not
self
.
directives
[
'testing'
]
:
defined_symbols
.
difference_update
(
self
.
RESERVED_SYMBOLS
)
def
remove_connections
(
symbol
):
...
...
@@ -452,7 +453,8 @@ class EBNFCompiler(Compiler):
remove_connections
(
self
.
root
)
for
leftover
in
defined_symbols
:
self
.
rules
[
leftover
][
0
].
add_error
((
'Rule "%s" is not connected to parser '
'root "%s"'
)
%
(
leftover
,
self
.
root
))
'root "%s" !'
)
%
(
leftover
,
self
.
root
)
+
' (Use directive "@testing=True" '
'to supress this error message.)'
)
# set root parser and assemble python grammar definition
...
...
@@ -528,8 +530,9 @@ class EBNFCompiler(Compiler):
return
rx
def
on_directive
(
self
,
node
:
Node
)
->
str
:
key
=
str
(
node
.
children
[
0
]).
lower
()
# cast(str, node.children[0].result).lower()
key
=
str
(
node
.
children
[
0
]).
lower
()
assert
key
not
in
self
.
directives
[
'tokens'
]
if
key
in
{
'comment'
,
'whitespace'
}:
if
node
.
children
[
1
].
parser
.
name
==
"list_"
:
if
len
(
node
.
children
[
1
].
result
)
!=
1
:
...
...
@@ -554,6 +557,10 @@ class EBNFCompiler(Compiler):
"/%s/ does not."
%
value
)
self
.
directives
[
key
]
=
value
elif
key
==
'testing'
:
value
=
str
(
node
.
children
[
1
])
self
.
directives
[
'testing'
]
=
value
.
lower
()
not
in
{
"off"
,
"false"
,
"no"
}
elif
key
==
'literalws'
:
value
=
{
item
.
lower
()
for
item
in
self
.
_compile
(
node
.
children
[
1
])}
if
(
len
(
value
-
{
'left'
,
'right'
,
'both'
,
'none'
})
>
0
...
...
DHParser/testing.py
View file @
ee075c8b
...
...
@@ -30,7 +30,7 @@ from DHParser import Node, error_messages
from
DHParser.toolkit
import
compact_sexpr
,
is_logging
from
DHParser.syntaxtree
import
MockParser
from
DHParser.ebnf
import
grammar_changed
from
DHParser.dsl
import
compile_on_disk
from
DHParser.dsl
import
CompilationError
,
compile_on_disk
def
mock_syntax_tree
(
sexpr
):
...
...
@@ -87,7 +87,7 @@ def mock_syntax_tree(sexpr):
return
Node
(
MockParser
(
name
,
':'
+
class_name
),
result
)
def
recompile_grammar
(
ebnf_filename
,
force
=
False
):
def
recompile_grammar
(
ebnf_filename
,
force
=
False
)
->
bool
:
"""Recompiles an ebnf-grammar if necessary, that is if either no
corresponding 'XXXXCompiler.py'-file exists or if that file is
outdated.
...
...
@@ -101,10 +101,11 @@ def recompile_grammar(ebnf_filename, force=False):
recompiled if it has been changed.
"""
if
os
.
path
.
isdir
(
ebnf_filename
):
success
=
True
for
entry
in
os
.
listdir
(
ebnf_filename
):
if
entry
.
lower
().
endswith
(
'.ebnf'
)
and
os
.
path
.
isfile
(
entry
):
recompile_grammar
(
entry
,
force
)
return
success
=
success
and
recompile_grammar
(
entry
,
force
)
return
success
base
,
ext
=
os
.
path
.
splitext
(
ebnf_filename
)
compiler_name
=
base
+
'Compiler.py'
...
...
@@ -119,14 +120,11 @@ def recompile_grammar(ebnf_filename, force=False):
for
e
in
errors
:
f
.
write
(
e
)
f
.
write
(
'
\n
'
)
return
False
if
not
errors
:
if
os
.
path
.
exists
(
base
+
'_errors.txt'
):
# if query_remove_error_files:
# answer = input('Remove obsolete file ' + base + '_errors.txt (y/n)? ').lower()
# if answer not in {'y', 'yes'}:
# return
os
.
remove
(
base
+
'_errors.txt'
)
if
not
errors
and
os
.
path
.
exists
(
base
+
'_errors.txt'
):
os
.
remove
(
base
+
'_errors.txt'
)
return
True
UNIT_STAGES
=
{
'match'
,
'fail'
,
'ast'
,
'cst'
,
'__ast__'
,
'__cst__'
}
...
...
DHParser/toolkit.py
View file @
ee075c8b
...
...
@@ -45,8 +45,8 @@ __all__ = ['logging',
'is_logging'
,
'log_dir'
,
'logfile_basename'
,
'supress_warnings'
,
'warnings'
,
#
'supress_warnings',
#
'warnings',
'line_col'
,
'error_messages'
,
'compact_sexpr'
,
...
...
@@ -127,24 +127,24 @@ def is_logging() -> bool:
return
False
@
contextlib
.
contextmanager
def
supress_warnings
(
supress
:
bool
=
True
):
global
SUPRESS_WARNINGS
try
:
save
=
SUPRESS_WARNINGS
except
NameError
:
save
=
False
# global default for warning supression is False
SUPRESS_WARNINGS
=
supress
yield
SUPRESS_WARNINGS
=
save
def
warnings
()
->
bool
:
global
SUPRESS_WARNINGS
try
:
return
not
SUPRESS_WARNINGS
except
NameError
:
return
True
#
@contextlib.contextmanager
#
def supress_warnings(supress: bool = True):
#
global SUPRESS_WARNINGS
#
try:
#
save = SUPRESS_WARNINGS
#
except NameError:
#
save = False # global default for warning supression is False
#
SUPRESS_WARNINGS = supress
#
yield
#
SUPRESS_WARNINGS = save
#
#
#
def warnings() -> bool:
#
global SUPRESS_WARNINGS
#
try:
#
return not SUPRESS_WARNINGS
#
except NameError:
#
return True
def
line_col
(
text
:
str
,
pos
:
int
)
->
Tuple
[
int
,
int
]:
...
...
examples/LaTeX/LaTeX.ebnf
View file @
ee075c8b
# latex Grammar
@ testing = True
@ whitespace = /[ \t]*\n?(?!\s*\n)[ \t]*/ # whitespace, including at most one linefeed
@ comment = /%.*(?:\n|$)/
...
...
examples/LaTeX/recompile_grammar.py
View file @
ee075c8b
...
...
@@ -25,7 +25,6 @@ import sys
sys
.
path
.
extend
([
'../../'
,
'../'
,
'./'
])
from
DHParser.testing
import
recompile_grammar
from
DHParser.toolkit
import
supress_warnings
with
supress_warnings
(
True
):
recompile_grammar
(
'.'
,
True
)
if
not
recompile_grammar
(
'.'
,
True
):
sys
.
exit
(
1
)
test/test_ebnf.py
View file @
ee075c8b
...
...
@@ -26,7 +26,7 @@ from multiprocessing import Pool
sys
.
path
.
extend
([
'../'
,
'./'
])
from
DHParser.toolkit
import
is_logging
,
compile_python_object
,
supress_warnings
from
DHParser.toolkit
import
is_logging
,
compile_python_object
from
DHParser.parsers
import
compile_source
,
Retrieve
,
WHITESPACE_PTYPE
,
nil_scanner
from
DHParser.ebnf
import
get_ebnf_grammar
,
get_ebnf_transformer
,
EBNFTransformer
,
get_ebnf_compiler
from
DHParser.dsl
import
CompilationError
,
compileDSL
,
DHPARSER_IMPORTS
,
parser_factory
...
...
@@ -349,8 +349,7 @@ class TestBoundaryCases:
unconnected = /.*/
"""
try
:
with
supress_warnings
(
False
):
grammar
=
parser_factory
(
ebnf
)()
grammar
=
parser_factory
(
ebnf
)()
assert
False
,
"EBNF compiler should complain about unconnected rules."
except
CompilationError
as
err
:
grammar_src
=
err
.
result
...
...
@@ -367,6 +366,12 @@ class TestBoundaryCases:
"a non-existant parser name!"
except
KeyError
:
pass
ebnf_testing
=
"@testing = True
\n
"
+
ebnf
try
:
grammar
=
parser_factory
(
ebnf_testing
)()
except
CompilationError
:
assert
False
,
"EBNF compiler should not complain about unconnected "
\
"rules when directive @testing is set."
class
TestSynonymDetection
:
...
...
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