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
f7fbe190
Commit
f7fbe190
authored
Feb 27, 2021
by
Eckhart Arnold
Browse files
small corrections
parent
5b1b56c4
Changes
2
Hide whitespace changes
Inline
Side-by-side
DHParser/ebnf.py
View file @
f7fbe190
...
...
@@ -17,10 +17,30 @@
"""
Module ``ebnf`` provides a self-hosting parser for EBNF-Grammars as
well as an EBNF-compiler that compiles an EBNF-Grammar into a
DHParser based Grammar class that can be executed to parse source text
Module ``ebnf`` provides an EBNF-parser-generator that compiles an
EBNF-Grammar into avPython-code that can be executed to parse source text
conforming to this grammar into concrete syntax trees.
With DHParser, Grammars can be specified either directly in Python-code
(see :py:mod:`DHParser.parse`) or in one of several EBNF-dialects. (Yes,
DHParser supports several different variants of EBNF! This makes it easy
to crate a parser directly from Grammars found in external sources.)
"EBNF" stands for the "Extended-Backus-Naur-Form" which is a common
formalism for specifying Grammars for context-free-languages.
(see https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form)
The recommended way of compiling grammars with DHParser is to either
write the EBNF-specification for that Grammar into a text-file and then
compile EBNF-source to an executable as well as importable Python-module
with the help of the "dhparser"-skript. Or, for bigger projects, to
create a new domain-specific-language-project with the DHParser-skript
as described in the step-by-step-guide.
However, here we will show how to compile an EBNF-specified grammar
from within Python-code and how to execute the parser that was
generated by compiling the grammar.
"""
...
...
@@ -42,7 +62,7 @@ from DHParser.parse import Parser, Grammar, mixin_comment, mixin_nonempty, Forwa
Text
,
Capture
,
Retrieve
,
Pop
,
optional_last_value
,
GrammarError
,
Whitespace
,
Always
,
Never
,
\
INFINITE
,
matching_bracket
,
ParseFunc
,
update_scanner
from
DHParser.preprocess
import
nil_preprocessor
,
PreprocessorFunc
from
DHParser.syntaxtree
import
Node
,
RootNode
,
WHITESPACE_PTYPE
,
TOKEN_PTYPE
,
EMPTY_NODE
from
DHParser.syntaxtree
import
Node
,
RootNode
,
WHITESPACE_PTYPE
,
TOKEN_PTYPE
from
DHParser.toolkit
import
load_if_file
,
escape_re
,
escape_control_characters
,
md5
,
\
sane_parser_name
,
re
,
expand_table
,
unrepr
,
compile_python_object
,
DHPARSER_PARENTDIR
,
\
RX_NEVER_MATCH
,
cython
...
...
@@ -492,7 +512,7 @@ class EBNFGrammar(Grammar):
set_parsefunc
(
self
.
free_char
,
self
.
free_char_parsefunc__
)
set_parsefunc
(
self
.
regex_heuristics
,
never
)
set_parsefunc
(
self
.
char_range_heuristics
,
always
)
elif
mode
==
'regex-like'
:
elif
mode
==
'regex-like'
:
set_parsefunc
(
self
.
free_char
,
self
.
free_char_parsefunc__
)
set_parsefunc
(
self
.
regex_heuristics
,
always
)
set_parsefunc
(
self
.
char_range_heuristics
,
always
)
...
...
@@ -978,10 +998,10 @@ WHITESPACE_TYPES = {'horizontal': r'[\t ]*', # default: horizontal
'linefeed'
:
r
'[ \t]*\n?(?!\s*\n)[ \t]*'
,
'vertical'
:
r
'\s*'
}
DROP_STRINGS
=
'strings'
DROP_WSPC
=
'whitespace'
DROP_REGEXP
=
'regexps'
DROP_VALUES
=
{
DROP_STRINGS
,
DROP_WSPC
,
DROP_REGEXP
}
DROP_STRINGS
=
'strings'
DROP_WSPC
=
'whitespace'
DROP_REGEXP
=
'regexps'
DROP_VALUES
=
{
DROP_STRINGS
,
DROP_WSPC
,
DROP_REGEXP
}
# Representation of Python code or, rather, something that will be output as Python code
ReprType
=
Union
[
str
,
unrepr
]
...
...
@@ -1495,7 +1515,7 @@ class EBNFCompiler(Compiler):
"""Returns the recursive paths from symbol to itself. If
sym is not recursive, the returned tuple (of paths) will be empty.
This method exists only for debugging (so far...)."""
path = []
path = []
# type: List[str]
recursive_paths = set() # type: Set[Tuple[str]]
def gather(sym: str):
...
...
@@ -2342,7 +2362,7 @@ class EBNFCompiler(Compiler):
"
-
parsers
,
not
:
" + nd.tag_name)
if not result[:7] == 'RegExp(':
self.deferred_tasks.append(lambda
:verify(node))
self.deferred_tasks.append(lambda:
verify(node))
return result
...
...
@@ -2365,8 +2385,8 @@ class EBNFCompiler(Compiler):
if self.anonymous_regexp.match(arg):
self.tree.new_error(
node,
(
'Retrieve operator "
%
s
" does not work with anonymous parsers like %s'
)
% (prefix, arg))
node, 'Retrieve operator "
%
s
" does not work with anonymous parsers like %s'
% (prefix, arg))
return arg
custom_args = [] # type: List[str]
...
...
@@ -2424,9 +2444,9 @@ class EBNFCompiler(Compiler):
"""
assert node.tag_name == 'counted'
assert len(node.children) == 2
r
a
ng
e
= node.get('range', None)
if r
a
ng
e
:
r = self.extract_range(r
a
ng
e
)
rng = node.get('range', None)
if rng:
r = self.extract_range(rng)
what = node.children[0]
assert what.tag_name != 'range'
else: # multiplier specified instead of range
...
...
DHParser/parse.py
View file @
f7fbe190
...
...
@@ -36,7 +36,7 @@ from typing import Callable, cast, List, Tuple, Set, AbstractSet, Dict, \
DefaultDict
,
Sequence
,
Union
,
Optional
,
Iterator
from
DHParser.configuration
import
get_config_value
from
DHParser.error
import
Error
,
ErrorCode
,
is_error
,
MANDATORY_CONTINUATION
,
\
from
DHParser.error
import
Error
,
ErrorCode
,
MANDATORY_CONTINUATION
,
\
UNDEFINED_RETRIEVE
,
PARSER_LOOKAHEAD_FAILURE_ONLY
,
\
PARSER_LOOKAHEAD_MATCH_ONLY
,
PARSER_STOPPED_BEFORE_END
,
PARSER_NEVER_TOUCHES_DOCUMENT
,
\
MALFORMED_ERROR_STRING
,
MANDATORY_CONTINUATION_AT_EOF
,
DUPLICATE_PARSERS_IN_ALTERNATIVE
,
\
...
...
Write
Preview
Supports
Markdown
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