Loading examples/yaml/grammar_tests/01_test_JSON_primitives.ini 0 → 100644 +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] examples/yaml/grammar_tests/02_test_JSON_elements.ini 0 → 100644 +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] examples/yaml/yamlCompiler.py 0 → 100755 +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]") Loading
examples/yaml/grammar_tests/01_test_JSON_primitives.ini 0 → 100644 +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]
examples/yaml/grammar_tests/02_test_JSON_elements.ini 0 → 100644 +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]
examples/yaml/yamlCompiler.py 0 → 100755 +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]")