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
9958d09b
Commit
9958d09b
authored
Aug 07, 2017
by
Eckhart Arnold
Browse files
- More documentation for EBNF-Compiler
parent
90d11281
Changes
2
Hide whitespace changes
Inline
Side-by-side
DHParser/ebnf.py
View file @
9958d09b
...
...
@@ -291,6 +291,55 @@ class EBNFCompiler(Compiler):
"""
Generates a Parser from an abstract syntax tree of a grammar specified
in EBNF-Notation.
Instances of this class must be called with the root-node of the
abstract syntax tree from an EBNF-specification of a formal language.
The returned value is the Python-source-code of a Grammar class for
this language that can be used to parse texts in this language.
See classes `parser.Compiler` and `parser.Grammar` for more information.
Addionally, class EBNFCompiler provides helper methods to generate
code-skeletons for a preprocessor, AST-transformation and full
compilation of the formal language. These method's names start with
the prefix `gen_`.
Attributes:
current_symbols - During compilation, a list containing the root
node of the currently compiled definition as first element
and then the nodes of the symbols that are referred to in
the currently compiled definition.
rules - Dictionary that maps rule names to a list of Nodes that
contain symbol-references in the definition of the rule.
The first item in the list is the node of the rule-
definition itself. Example:
`alternative = a | b`
Now `[str(node) for node in self.rules['alternative']]`
yields `['alternative = a | b', 'a', 'b']`
symbols - A mapping of symbol names to their first usage (not
their definition!) in the EBNF source.
variables - A set of symbols names that are used with the
Pop or Retrieve operator. Because the values of these
symbols need to be captured they are called variables.
See `test_parser.TestPopRetrieve` for an example.
recursive - A set of symbols that are used recursively and
therefore require a `Forward`-operator.
deferred_taks - A list of callables that is filled during
compilatation, but that will be executed only after
compilation has finished. Typically, it contains
sementatic checks that require information that
is only available upon completion of compilation.
root - The name of the root symbol.
directives - A dictionary of all directives and their default
values.
"""
COMMENT_KEYWORD
=
"COMMENT__"
WHITESPACE_KEYWORD
=
"WSP__"
...
...
@@ -317,7 +366,6 @@ class EBNFCompiler(Compiler):
self
.
current_symbols
=
[]
# type: List[Node]
self
.
symbols
=
{}
# type: Dict[str, Node]
self
.
variables
=
set
()
# type: Set[str]
# self.definitions = [] # type: List[Tuple[str, str]]
self
.
recursive
=
set
()
# type: Set[str]
self
.
deferred_tasks
=
[]
# type: List[Callable]
self
.
root
=
""
# type: str
...
...
@@ -335,12 +383,20 @@ class EBNFCompiler(Compiler):
# methods for generating skeleton code for preprocessor, transformer, and compiler
def
gen_preprocessor_skeleton
(
self
)
->
str
:
"""
Returns Python-skeleton-code for a preprocessor-function for
the previously compiled formal language.
"""
name
=
self
.
grammar_name
+
"Preprocessor"
return
"def %s(text):
\n
return text
\n
"
%
name
\
+
PREPROCESSOR_FACTORY
.
format
(
NAME
=
self
.
grammar_name
)
def
gen_transformer_skeleton
(
self
)
->
str
:
"""
Returns Python-skeleton-code for the AST-transformation for the
previously compiled formal language.
"""
if
not
self
.
rules
:
raise
EBNFCompilerError
(
'Compiler must be run before calling '
'"gen_transformer_Skeleton()"!'
)
...
...
@@ -360,6 +416,10 @@ class EBNFCompiler(Compiler):
def
gen_compiler_skeleton
(
self
)
->
str
:
"""
Returns Python-skeleton-code for a Compiler-class for the
previously compiled formal language.
"""
if
not
self
.
rules
:
raise
EBNFCompilerError
(
'Compiler has not been run before calling '
'"gen_Compiler_Skeleton()"!'
)
...
...
test/test_parser.py
View file @
9958d09b
...
...
@@ -232,7 +232,7 @@ class TestPopRetrieve:
mini_language
=
"""
document = { text | codeblock }
codeblock = delimiter { text | (!:delimiter delimiter_sign) } ::delimiter
delimiter = delimiter_sign # never use delimiter between capture and
retrieve!!
!
delimiter = delimiter_sign # never use delimiter between capture and
pop except for retrival
!
delimiter_sign = /`+/
text = /[^`]+/
"""
...
...
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