Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 0e289db1 authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

small corrections; test for load_compiler_suite

parent c3899a9a
......@@ -28,4 +28,4 @@ from .versionnumber import __version__
__author__ = "Eckhart Arnold <arnold@badw.de>"
__copyright__ = "http://www.apache.org/licenses/LICENSE-2.0"
__all__ = ['toolkit', 'syntaxtree', 'parsers', 'ebnf', 'dsl']
# __all__ = ['toolkit', 'syntaxtree', 'parsers', 'ebnf', 'dsl'] # flat namespace
......@@ -39,7 +39,7 @@ __all__ = ['GrammarError',
'load_compiler_suite',
'compileDSL',
'compileEBNF',
'compile_parser',
'parser_factory',
'compile_on_disk']
......@@ -172,7 +172,7 @@ def compileDSL(text_or_file, scanner, dsl_grammar, ast_transformation, compiler)
compilation error.
Raises:
CompilationError if any errors occured during compilation
CompilationError if any errors occurred during compilation
"""
assert isinstance(text_or_file, str)
assert isinstance(compiler, CompilerBase)
......@@ -194,25 +194,27 @@ def compileEBNF(ebnf_src, branding = "DSL"):
Args:
ebnf_src(str): Either the file name of an EBNF grammar or
the EBNF grammar itself as a string.
branding (str or bool): Branding name for the compiler
suite source code.
branding (str): Branding name for the compiler suite source
code.
Returns:
The complete compiler suite skeleton as Python source code.
Raises:
CompilationError if any errors occurred during compilation
"""
grammar = get_ebnf_grammar()
if branding == True: branding = "DSL"
compiler = get_ebnf_compiler(branding or "DSL", ebnf_src)
compiler = get_ebnf_compiler(branding , ebnf_src)
grammar_src = compileDSL(ebnf_src, nil_scanner, grammar, EBNFTransformer, compiler)
src = [DHPARSER_IMPORTS,
compiler.gen_scanner_skeleton(),
grammar_src,
compiler.gen_transformer_skeleton(),
compiler.gen_compiler_skeleton(),
DHPARSER_MAIN.format(NAME=branding)]
src = ["#/usr/bin/python\n",
SECTION_MARKER.format(marker=SYMBOLS_SECTION), DHPARSER_IMPORTS,
SECTION_MARKER.format(marker=SCANNER_SECTION), compiler.gen_scanner_skeleton(),
SECTION_MARKER.format(marker=PARSER_SECTION), grammar_src,
SECTION_MARKER.format(marker=AST_SECTION), compiler.gen_transformer_skeleton(),
SECTION_MARKER.format(marker=COMPILER_SECTION), compiler.gen_compiler_skeleton(),
SECTION_MARKER.format(marker=SYMBOLS_SECTION), DHPARSER_MAIN.format(NAME=branding)]
return '\n'.join(src)
def compile_parser(ebnf_src, branding="DSL"):
def parser_factory(ebnf_src, branding="DSL"):
"""Compiles an EBNF grammar and returns a grammar-parser factory
function for that grammar.
......@@ -250,19 +252,18 @@ def load_compiler_suite(compiler_suite):
'Please delete or repair file manually.')
# TODO: Compile in one step and pick parts from namespace later ?
scanner = compile_python_object(imports + scanner_py, 'get_\w*_scanner$')
parser = compile_python_object(imports + parser_py, 'get_\w*_grammar$')
ast = compile_python_object(imports + ast_py, 'get_\w*_transformer$')
compiler = compile_python_object(imports + compiler_py, 'get_\w*_compiler$')
else:
# assume source is an ebnf grammar
# assume source is an ebnf grammar. Is there really any reasonable application case for this?
with logging(False):
parser_py, errors, AST = compile_source(source, None,
compile_py, errors, AST = compile_source(source, None,
get_ebnf_grammar(), get_ebnf_transformer(), get_ebnf_compiler())
if errors:
raise GrammarError('\n\n'.join(errors), source)
scanner = get_ebnf_scanner
ast = get_ebnf_transformer
compiler = get_ebnf_compiler
parser = compile_python_object(DHPARSER_IMPORTS + parser_py, 'get_\w*_grammar$')
compiler = compile_python_object(imports + compiler_py, 'get_\w*_compiler$')
return scanner, parser, ast, compiler
......
......@@ -20,11 +20,15 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
import inspect
import os
import sys
sys.path.extend(['../', './'])
from DHParser.dsl import compile_on_disk, run_compiler, compileDSL, compileEBNF, compile_parser
from DHParser.parsers import GrammarBase, CompilerBase
from DHParser.ebnf import get_ebnf_compiler, get_ebnf_scanner, get_ebnf_transformer
from DHParser.dsl import compile_on_disk, run_compiler, compileDSL, compileEBNF, parser_factory, \
load_compiler_suite
ARITHMETIC_EBNF = """
......@@ -44,9 +48,9 @@ class TestCompileFunctions:
parser_src = compileEBNF(ARITHMETIC_EBNF, branding="CustomDSL")
assert isinstance(parser_src, str), str(type(parser_src))
assert parser_src.find('get_CustomDSL') >= 0
parser_factory = compile_parser(ARITHMETIC_EBNF, branding="TestDSL")
assert callable(parser_factory)
parser = parser_factory()
factory = parser_factory(ARITHMETIC_EBNF, branding="TestDSL")
assert callable(factory)
parser = factory()
result = parser("5 + 3 * 4")
assert not result.error_flag
result = parser("5A + 4B ** 4C")
......@@ -78,6 +82,18 @@ class TestCompilerGeneration:
os.remove(name)
pass
def test_load_compiler_suite(self):
src = compileEBNF(self.trivial_lang, "Trivial")
scanner, parser, transformer, compiler = load_compiler_suite(src)
scanner = scanner()
parser = parser()
transformer = transformer()
compiler = compiler()
assert callable(scanner)
assert isinstance(parser, GrammarBase)
assert callable(transformer)
assert isinstance(compiler, CompilerBase)
def test_compiling_functions(self):
# test if cutting and reassembling of compiler suite works:
errors = compile_on_disk(self.grammar_name)
......
......@@ -28,7 +28,7 @@ sys.path.extend(['../', './'])
from DHParser.toolkit import is_logging
from DHParser.parsers import compile_source, Retrieve, WHITESPACE_KEYWORD, nil_scanner
from DHParser.ebnf import get_ebnf_grammar, get_ebnf_transformer, EBNFTransformer, get_ebnf_compiler
from DHParser.dsl import compileEBNF, compileDSL, compile_parser
from DHParser.dsl import compileEBNF, compileDSL, parser_factory
class TestDirectives:
......@@ -42,7 +42,7 @@ class TestDirectives:
def test_whitespace_linefeed(self):
lang = "@ whitespace = linefeed\n" + self.mini_language
MinilangParser = compile_parser(lang)
MinilangParser = parser_factory(lang)
parser = MinilangParser()
assert parser
syntax_tree = parser("3 + 4 * 12")
......@@ -58,7 +58,7 @@ class TestDirectives:
def test_whitespace_vertical(self):
lang = "@ whitespace = vertical\n" + self.mini_language
parser = compile_parser(lang)()
parser = parser_factory(lang)()
assert parser
syntax_tree = parser("3 + 4 * 12")
assert not syntax_tree.collect_errors()
......@@ -71,7 +71,7 @@ class TestDirectives:
def test_whitespace_horizontal(self):
lang = "@ whitespace = horizontal\n" + self.mini_language
parser = compile_parser(lang)()
parser = parser_factory(lang)()
assert parser
syntax_tree = parser("3 + 4 * 12")
assert not syntax_tree.collect_errors()
......@@ -131,8 +131,8 @@ class TestPopRetrieve:
"""
def setup(self):
self.minilang_parser = compile_parser(self.mini_language)()
self.minilang_parser2 = compile_parser(self.mini_lang2)()
self.minilang_parser = parser_factory(self.mini_language)()
self.minilang_parser2 = parser_factory(self.mini_lang2)()
@staticmethod
def opening_delimiter(node, name):
......
......@@ -28,7 +28,7 @@ from DHParser.syntaxtree import no_operation, traverse, remove_expendables, \
replace_by_single_child, reduce_single_child, flatten
from DHParser.parsers import compile_source
from DHParser.ebnf import get_ebnf_grammar, get_ebnf_transformer, get_ebnf_compiler
from DHParser.dsl import compile_parser, DHPARSER_IMPORTS
from DHParser.dsl import parser_factory, DHPARSER_IMPORTS
ARITHMETIC_EBNF = """
......@@ -72,7 +72,7 @@ class TestInfiLoopsAndRecursion:
def test_direct_left_recursion(self):
minilang = ARITHMETIC_EBNF
snippet = "5 + 3 * 4"
parser = compile_parser(minilang)()
parser = parser_factory(minilang)()
assert parser
syntax_tree = parser(snippet)
assert not syntax_tree.collect_errors()
......@@ -87,7 +87,7 @@ class TestInfiLoopsAndRecursion:
def test_inifinite_loops(self):
minilang = """not_forever = { // } \n"""
snippet = " "
parser = compile_parser(minilang)()
parser = parser_factory(minilang)()
syntax_tree = parser(snippet)
assert syntax_tree.error_flag
# print(syntax_tree.collect_errors())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment