Commit 7d533d69 authored by eckhart's avatar eckhart
Browse files

refactoring

parent cf5ef3ad
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line

[match:CHARACTERS]

[ast:CHARACTERS]

[fail:CHARACTERS]


[match:ESCAPE]

[ast:ESCAPE]

[fail:ESCAPE]


[match:HEX]

[ast:HEX]

[fail:HEX]


[match:INT]

[ast:INT]

[fail:INT]


[match:FRAC]

[ast:FRAC]

[fail:FRAC]


[match:EXP]

[ast:EXP]

[fail:EXP]


[match:EOF]

[ast:EOF]

[fail:EOF]
+70 −0
Original line number Diff line number Diff line

[match:json]

[ast:json]

[fail:json]


[match:element]

[ast:element]

[fail:element]


[match:value]

[ast:value]

[fail:value]


[match:object]

[ast:object]

[fail:object]


[match:member]

[ast:member]

[fail:member]


[match:array]

[ast:array]

[fail:array]


[match:string]

[ast:string]

[fail:string]


[match:number]

[ast:number]

[fail:number]


[match:bool]

[ast:bool]

[fail:bool]


[match:null]

[ast:null]

[fail:null]
+274 −0
Original line number Diff line number Diff line
#!/usr/bin/python3

#######################################################################
#
# SYMBOLS SECTION - Can be edited. Changes will be preserved.
#
#######################################################################


import collections
from functools import partial
import os
import sys

sys.path.append(r'/home/eckhart/Entwicklung/MLW-DSL/DHParser-submodule')

try:
    import regex as re
except ImportError:
    import re
from DHParser import logging, is_filename, load_if_file, \
    Grammar, Compiler, nil_preprocessor, PreprocessorToken, Whitespace, DropWhitespace, \
    Lookbehind, Lookahead, Alternative, Pop, Token, DropToken, Synonym, AllOf, SomeOf, \
    Unordered, Option, NegativeLookbehind, OneOrMore, RegExp, Retrieve, Series, Capture, \
    ZeroOrMore, Forward, NegativeLookahead, Required, mixin_comment, compile_source, \
    grammar_changed, last_value, counterpart, PreprocessorFunc, is_empty, \
    Node, TransformationFunc, TransformationDict, transformation_factory, traverse, \
    remove_children_if, move_adjacent, normalize_whitespace, is_anonymous, matches_re, \
    reduce_single_child, replace_by_single_child, replace_or_reduce, remove_whitespace, \
    replace_by_children, remove_empty, remove_tokens, flatten, is_insignificant_whitespace, \
    collapse, collapse_if, replace_content, WHITESPACE_PTYPE, TOKEN_PTYPE, \
    remove_nodes, remove_content, remove_brackets, change_tag_name, remove_anonymous_tokens, \
    keep_children, is_one_of, not_one_of, has_content, apply_if, remove_first, remove_last, \
    remove_anonymous_empty, keep_nodes, traverse_locally, strip, lstrip, rstrip, \
    replace_content, replace_content_by, forbid, assert_content, remove_infix_operator, \
    error_on, recompile_grammar, left_associative, lean_left, set_config_value, \
    get_config_value, XML_SERIALIZATION, SXPRESSION_SERIALIZATION, COMPACT_SERIALIZATION, \
    JSON_SERIALIZATION, THREAD_LOCALS, access_presets, finalize_presets 


#######################################################################
#
# PREPROCESSOR SECTION - Can be edited. Changes will be preserved.
#
#######################################################################

def yamlPreprocessor(text):
    return text, lambda i: i

def get_preprocessor() -> PreprocessorFunc:
    return yamlPreprocessor


#######################################################################
#
# PARSER SECTION - Don't edit! CHANGES WILL BE OVERWRITTEN!
#
#######################################################################

class yamlGrammar(Grammar):
    r"""Parser for a yaml source file.
    """
    element = Forward()
    value = Forward()
    source_hash__ = "32d03563d86b8ca074f0155c29076a36"
    static_analysis_pending__ = [True]
    parser_initialization__ = ["upon instantiation"]
    resume_rules__ = {}
    COMMENT__ = r'(?:\/\/|#).*'
    WHITESPACE__ = r'\s*'
    WSP_RE__ = mixin_comment(whitespace=WHITESPACE__, comment=COMMENT__)
    dwsp__ = DropWhitespace(WSP_RE__)
    EOF = NegativeLookahead(RegExp('.'))
    EXP = Option(Series(Alternative(DropToken("E"), DropToken("e")), Option(Alternative(DropToken("+"), DropToken("-"))), RegExp('[0-9]+')))
    FRAC = Option(Series(DropToken("."), RegExp('[0-9]+')))
    INT = Alternative(Series(Option(DropToken("-")), RegExp('[0-9]')), RegExp('[1-9][0-9]+'))
    HEX = RegExp('[0-9a-fA-F]')
    ESCAPE = Alternative(RegExp('\\\\[/bnrt\\\\]'), Series(RegExp('\\\\u'), HEX, HEX, HEX, HEX))
    CHARACTERS = ZeroOrMore(Alternative(RegExp('[^"\\\\]+'), ESCAPE))
    null = Series(Token("null"), dwsp__)
    bool = Alternative(Series(RegExp('true'), dwsp__), Series(RegExp('false'), dwsp__))
    number = Series(INT, FRAC, EXP, dwsp__)
    string = Series(DropToken('"'), CHARACTERS, DropToken('"'), dwsp__)
    array = Series(Series(DropToken("["), dwsp__), Option(Series(value, ZeroOrMore(Series(Series(DropToken(","), dwsp__), value)))), Series(DropToken("]"), dwsp__))
    member = Series(string, Series(DropToken(":"), dwsp__), element)
    object = Series(Series(DropToken("{"), dwsp__), Option(Series(member, ZeroOrMore(Series(Series(DropToken(","), dwsp__), member)))), Series(DropToken("}"), dwsp__))
    value.set(Alternative(object, array, string, number, bool, null))
    element.set(Synonym(value))
    json = Series(dwsp__, element, EOF)
    root__ = json
    
def get_grammar() -> yamlGrammar:
    """Returns a thread/process-exclusive yamlGrammar-singleton."""
    try:
        grammar = THREAD_LOCALS.yaml_00000001_grammar_singleton
    except AttributeError:
        THREAD_LOCALS.yaml_00000001_grammar_singleton = yamlGrammar()
        if hasattr(get_grammar, 'python_src__'):
            THREAD_LOCALS.yaml_00000001_grammar_singleton.python_src__ = get_grammar.python_src__
        grammar = THREAD_LOCALS.yaml_00000001_grammar_singleton
    return grammar


#######################################################################
#
# AST SECTION - Can be edited. Changes will be preserved.
#
#######################################################################

yaml_AST_transformation_table = {
    # AST Transformations for the yaml-grammar
    "<": flatten,
    "json": [],
    "element": [],
    "value": [],
    "object": [],
    "member": [],
    "array": [],
    "string": [],
    "number": [],
    "bool": [],
    "null": [],
    "CHARACTERS": [],
    "ESCAPE": [],
    "HEX": [],
    "INT": [],
    "FRAC": [],
    "EXP": [],
    "EOF": [],
    "*": replace_by_single_child
}


def CreateyamlTransformer() -> TransformationFunc:
    """Creates a transformation function that does not share state with other
    threads or processes."""
    return partial(traverse, processing_table=yaml_AST_transformation_table.copy())

def get_transformer() -> TransformationFunc:
    """Returns a thread/process-exclusive transformation function."""
    try:
        transformer = THREAD_LOCALS.yaml_00000001_transformer_singleton
    except AttributeError:
        THREAD_LOCALS.yaml_00000001_transformer_singleton = CreateyamlTransformer()
        transformer = THREAD_LOCALS.yaml_00000001_transformer_singleton
    return transformer


#######################################################################
#
# COMPILER SECTION - Can be edited. Changes will be preserved.
#
#######################################################################

class yamlCompiler(Compiler):
    """Compiler for the abstract-syntax-tree of a yaml source file.
    """

    def __init__(self):
        super(yamlCompiler, self).__init__()

    def reset(self):
        super().reset()
        # initialize your variables here, not in the constructor!

    def on_json(self, node):
        return self.fallback_compiler(node)

    # def on_element(self, node):
    #     return node

    # def on_value(self, node):
    #     return node

    # def on_object(self, node):
    #     return node

    # def on_member(self, node):
    #     return node

    # def on_array(self, node):
    #     return node

    # def on_string(self, node):
    #     return node

    # def on_number(self, node):
    #     return node

    # def on_bool(self, node):
    #     return node

    # def on_null(self, node):
    #     return node

    # def on_CHARACTERS(self, node):
    #     return node

    # def on_ESCAPE(self, node):
    #     return node

    # def on_HEX(self, node):
    #     return node

    # def on_INT(self, node):
    #     return node

    # def on_FRAC(self, node):
    #     return node

    # def on_EXP(self, node):
    #     return node

    # def on_EOF(self, node):
    #     return node


def get_compiler() -> yamlCompiler:
    """Returns a thread/process-exclusive yamlCompiler-singleton."""
    try:
        compiler = THREAD_LOCALS.yaml_00000001_compiler_singleton
    except AttributeError:
        THREAD_LOCALS.yaml_00000001_compiler_singleton = yamlCompiler()
        compiler = THREAD_LOCALS.yaml_00000001_compiler_singleton
    return compiler


#######################################################################
#
# END OF DHPARSER-SECTIONS
#
#######################################################################

def compile_src(source, log_dir=''):
    """Compiles ``source`` and returns (result, errors, ast).
    """
    with logging(log_dir):
        compiler = get_compiler()
        result_tuple = compile_source(source, get_preprocessor(),
                                      get_grammar(),
                                      get_transformer(), compiler)
    return result_tuple


if __name__ == "__main__":
    # recompile grammar if needed
    grammar_path = os.path.abspath(__file__).replace('Compiler.py', '.ebnf')
    if os.path.exists(grammar_path):
        if not recompile_grammar(grammar_path, force=False,
                                  notify=lambda:print('recompiling ' + grammar_path)):
            error_file = os.path.basename(__file__).replace('Compiler.py', '_ebnf_ERRORS.txt')
            with open(error_file, encoding="utf-8") as f:
                print(f.read())
            sys.exit(1)
    else:
        print('Could not check whether grammar requires recompiling, '
              'because grammar was not found at: ' + grammar_path)

    if len(sys.argv) > 1:
        # compile file
        file_name, log_dir = sys.argv[1], ''
        if file_name in ['-d', '--debug'] and len(sys.argv) > 2:
            file_name, log_dir = sys.argv[2], 'LOGS'
        result, errors, _ = compile_src(file_name, log_dir)
        if errors:
            cwd = os.getcwd()
            rel_path = file_name[len(cwd):] if file_name.startswith(cwd) else file_name
            for error in errors:
                print(rel_path + ':' + str(error))
            sys.exit(1)
        else:
            print(result.as_xml() if isinstance(result, Node) else result)
    else:
        print("Usage: yamlCompiler.py [FILENAME]")