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
a765df39
Commit
a765df39
authored
Aug 07, 2017
by
Eckhart Arnold
Browse files
- more hints for AST-transformation from EBNFCompiler
parent
9958d09b
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
DHParser/dsl.py
View file @
a765df39
...
...
@@ -82,7 +82,7 @@ from DHParser import logging, is_filename, load_if_file, \\
last_value, counterpart, accumulate, PreprocessorFunc,
\\
Node, TransformationFunc, TRUE_CONDITION,
\\
traverse, remove_children_if, merge_children, is_anonymous,
\\
reduce_single_child, replace_by_single_child, remove_whitespace,
\\
reduce_single_child, replace_by_single_child,
replace_or_reduce,
remove_whitespace,
\\
remove_expendables, remove_empty, remove_tokens, flatten, is_whitespace,
\\
is_empty, is_expendable, collapse, replace_content, WHITESPACE_PTYPE, TOKEN_PTYPE,
\\
remove_parser, remove_content, remove_brackets, replace_parser,
\\
...
...
DHParser/ebnf.py
View file @
a765df39
...
...
@@ -330,6 +330,9 @@ class EBNFCompiler(Compiler):
recursive - A set of symbols that are used recursively and
therefore require a `Forward`-operator.
definitions - A dictionary of definitions. Other than `rules`
this maps the symbols to their compiled definienda.
deferred_taks - A list of callables that is filled during
compilatation, but that will be executed only after
compilation has finished. Typically, it contains
...
...
@@ -367,6 +370,7 @@ class EBNFCompiler(Compiler):
self
.
symbols
=
{}
# type: Dict[str, Node]
self
.
variables
=
set
()
# type: Set[str]
self
.
recursive
=
set
()
# type: Set[str]
self
.
definitions
=
{}
# type: Dict[str, str]
self
.
deferred_tasks
=
[]
# type: List[Callable]
self
.
root
=
""
# type: str
self
.
directives
=
{
'whitespace'
:
self
.
WHITESPACE
[
'horizontal'
],
...
...
@@ -407,9 +411,15 @@ class EBNFCompiler(Compiler):
self
.
grammar_name
+
'-grammar'
]
transtable
.
append
(
' "+": remove_empty,'
)
for
name
in
self
.
rules
:
transtable
.
append
(
' "'
+
name
+
'": [],'
)
tf
=
'[]'
rule
=
self
.
definitions
[
name
]
if
rule
.
startswith
(
'Alternative'
):
tf
=
'[replace_or_reduce]'
elif
rule
.
startswith
(
'Synonym'
):
tf
=
'[replace_by_single_child]'
transtable
.
append
(
' "'
+
name
+
'": %s,'
%
tf
)
transtable
.
append
(
' ":Token, :RE": reduce_single_child,'
)
transtable
+=
[
'
#
"*": replace_by_single_child'
,
'}'
,
''
,
tf_name
+
transtable
+=
[
' "*": replace_by_single_child'
,
'}'
,
''
,
tf_name
+
' = partial(traverse, processing_table=%s)'
%
tt_name
,
''
]
transtable
+=
[
TRANSFORMER_FACTORY
.
format
(
NAME
=
self
.
grammar_name
)]
return
'
\n
'
.
join
(
transtable
)
...
...
@@ -560,6 +570,7 @@ class EBNFCompiler(Compiler):
assert
nd
.
parser
.
name
==
"directive"
,
nd
.
as_sxpr
()
self
.
compile
(
nd
)
node
.
error_flag
=
node
.
error_flag
or
nd
.
error_flag
self
.
definitions
.
update
(
definitions
)
return
self
.
assemble_parser
(
definitions
,
node
)
...
...
DHParser/transform.py
View file @
a765df39
...
...
@@ -39,8 +39,10 @@ __all__ = ('transformation_factory',
'key_parser_name'
,
'key_tag_name'
,
'traverse'
,
'is_named'
,
'replace_by_single_child'
,
'reduce_single_child'
,
'replace_or_reduce'
,
'replace_parser'
,
'collapse'
,
'merge_children'
,
...
...
@@ -235,6 +237,21 @@ def TRUE_CONDITION(node):
return
True
def
replace_child
(
node
):
assert
len
(
node
.
children
)
==
1
if
not
node
.
children
[
0
].
parser
.
name
:
node
.
children
[
0
].
parser
.
name
=
node
.
parser
.
name
node
.
parser
=
node
.
children
[
0
].
parser
node
.
_errors
.
extend
(
node
.
children
[
0
].
_errors
)
node
.
result
=
node
.
result
[
0
].
result
def
reduce_child
(
node
):
assert
len
(
node
.
children
)
==
1
node
.
_errors
.
extend
(
node
.
children
[
0
].
_errors
)
node
.
result
=
node
.
result
[
0
].
result
@
transformation_factory
(
Callable
)
def
replace_by_single_child
(
node
,
condition
=
TRUE_CONDITION
):
"""Remove single branch node, replacing it by its immediate descendant
...
...
@@ -242,12 +259,8 @@ def replace_by_single_child(node, condition=TRUE_CONDITION):
(In case the descendant's name is empty (i.e. anonymous) the
name of this node's parser is kept.)
"""
if
node
.
children
and
len
(
node
.
result
)
==
1
and
condition
(
node
.
children
[
0
]):
if
not
node
.
result
[
0
].
parser
.
name
:
node
.
result
[
0
].
parser
.
name
=
node
.
parser
.
name
node
.
parser
=
node
.
result
[
0
].
parser
node
.
_errors
.
extend
(
node
.
result
[
0
].
_errors
)
node
.
result
=
node
.
result
[
0
].
result
if
len
(
node
.
children
)
==
1
and
condition
(
node
.
children
[
0
]):
replace_child
(
node
)
@
transformation_factory
(
Callable
)
...
...
@@ -257,9 +270,23 @@ def reduce_single_child(node, condition=TRUE_CONDITION):
If the condition evaluates to false on the descendant, it will not
be reduced.
"""
if
node
.
children
and
len
(
node
.
result
)
==
1
and
condition
(
node
.
children
[
0
]):
node
.
_errors
.
extend
(
node
.
result
[
0
].
_errors
)
node
.
result
=
node
.
result
[
0
].
result
if
len
(
node
.
children
)
==
1
and
condition
(
node
.
children
[
0
]):
reduce_child
(
node
)
def
is_named
(
node
):
return
node
.
parser
.
name
@
transformation_factory
(
Callable
)
def
replace_or_reduce
(
node
,
condition
=
is_named
):
"""Replaces node by a single child, if condition is met on child,
otherwise (i.e. if the child is anonymous) reduces the child.
"""
if
len
(
node
.
children
)
==
1
and
condition
(
node
.
children
[
0
]):
replace_child
(
node
)
else
:
reduce_child
(
node
)
@
transformation_factory
...
...
dhparser.py
View file @
a765df39
...
...
@@ -77,6 +77,7 @@ def selftest() -> bool:
print
(
"
\n\n
STAGE 2: Selfhosting-test: Trying to compile EBNF-Grammar with generated parser...
\n
"
)
selfhosted_ebnf_parser
=
compileDSL
(
ebnf_src
,
None
,
generated_ebnf_parser
,
ebnf_transformer
,
ebnf_compiler
)
ebnf_compiler
.
gen_transformer_skeleton
()
print
(
selfhosted_ebnf_parser
)
print
(
"
\n\n
Selftest SUCCEEDED :-)
\n\n
"
)
return
True
...
...
examples/LaTeX/LaTeX.ebnf
View file @
a765df39
...
...
@@ -64,12 +64,12 @@ itemize = "\begin{itemize}" [PARSEP] { item } §"\end{itemize}"
enumerate = "\begin{enumerate}" [PARSEP] {item } §"\end{enumerate}"
item = "\item" [PARSEP] sequence
figure = "\begin{figure}" sequence "\end{figure}"
quotation = ("\begin{quotation}" sequence "\end{quotation}")
| ("\begin{quote}" sequence "\end{quote}")
verbatim = "\begin{verbatim}" sequence "\end{verbatim}"
table = "\begin{tabular}" table_config sequence "\end{tabular}"
table_config = "{" /[lcr|]+/~ "}"
figure = "\begin{figure}" sequence
§
"\end{figure}"
quotation = ("\begin{quotation}" sequence
§
"\end{quotation}")
| ("\begin{quote}" sequence
§
"\end{quote}")
verbatim = "\begin{verbatim}" sequence
§
"\end{verbatim}"
table = "\begin{tabular}" table_config sequence
§
"\end{tabular}"
table_config = "{" /[lcr|]+/~
§
"}"
#### paragraphs and sequences of paragraphs ####
...
...
@@ -92,7 +92,7 @@ end_inline_env = end_environment
begin_environment = "\begin{" §NAME §"}"
end_environment = "\end{" §::NAME §"}"
inline_math = "$" /[^$]*/ "$"
inline_math = "$" /[^$]*/
§
"$"
#### commands ####
...
...
examples/LaTeX/LaTeXCompiler.py_old
deleted
100644 → 0
View file @
9958d09b
This diff is collapsed.
Click to expand it.
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