From 60653c5f8919851115167ec1e92b52b9c19f295b Mon Sep 17 00:00:00 2001 From: Eckhart Arnold Date: Mon, 17 Apr 2017 09:07:23 +0200 Subject: [PATCH] refactorings (last commit already): EBNFcompiler renamed to ebnf.py DSLsupport renamed to dsl.py --- examples/LaTeX/LaTeX_compiler.py | 237 +++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 examples/LaTeX/LaTeX_compiler.py diff --git a/examples/LaTeX/LaTeX_compiler.py b/examples/LaTeX/LaTeX_compiler.py new file mode 100644 index 00000000..05566727 --- /dev/null +++ b/examples/LaTeX/LaTeX_compiler.py @@ -0,0 +1,237 @@ +#!/usr/bin/python + +####################################################################### +# +# SYMBOLS SECTION - Can be edited. Changes will be preserved. +# +####################################################################### + + +from functools import partial +import sys +try: + import regex as re +except ImportError: + import re +from DHParser.toolkit import load_if_file +from DHParser.parsers import GrammarBase, CompilerBase, nil_scanner, \ + Lookbehind, Lookahead, Alternative, Pop, Required, Token, \ + Optional, NegativeLookbehind, OneOrMore, RegExp, Retrieve, Sequence, RE, Capture, \ + ZeroOrMore, Forward, NegativeLookahead, mixin_comment, full_compilation +from DHParser.syntaxtree import Node, remove_enclosing_delimiters, remove_children_if, \ + reduce_single_child, replace_by_single_child, remove_whitespace, TOKEN_KEYWORD, \ + no_operation, remove_expendables, remove_tokens, flatten, WHITESPACE_KEYWORD, \ + is_whitespace, is_expendable + + +####################################################################### +# +# SCANNER SECTION - Can be edited. Changes will be preserved. +# +####################################################################### + +def LaTeXScanner(text): + return text + + +####################################################################### +# +# PARSER SECTION - Don't edit! CHANGES WILL BE OVERWRITTEN! +# +####################################################################### + +class LaTeXGrammar(GrammarBase): + r"""Parser for a LaTeX source file, with this grammar: + + # latex Grammar + + @ whitespace = /[ \t]*\n?(?!\s*\n)[ \t]*/ + @ comment = /%.*(?:\n|$)/ + + genericenv = beginenv sequence endenv + beginenv = "\begin" §( "{" name "}" ) + endenv = "\end" §( "{" ::name "}" ) + + name = ~/\w+/ + + genericcmd = command [ config ] block + command = /\\\w+/ + config = "[" cfgtext §"]" + + sequence = { partext | parblock } + + parblock = "{" { partext | parblock } §"}" + block = "{" { text | block } §"}" + + partext = text | par + text = cfgtext | brackets + cfgtext = chunk | wspc | escaped + + escaped = /\\[%$&]/ + brackets = /[\[\]]/ # left and right square brackets: [ ] + chunk = /[^\\%$&\{\}\[\]\s\n]+/ # some piece of text excluding whitespace, + # linefeed and special characters + wspc = /[ \t]*\n?(?!\s*\n)[ \t]*/ # whitespace, including at most one linefeed + lf = /[ \t]*\n(?!\s*\n)/ # a linefeed, but not an empty line (i.e. par) + par = /\s*\n\s*\n/ # at least one empty line, i.e. + # [whitespace] linefeed [whitespace] linefeed + """ + block = Forward() + parblock = Forward() + source_hash__ = "9f01a5f7c1df86e103f920fda0339d14" + parser_initialization__ = "upon instatiation" + COMMENT__ = r'%.*(?:\n|$)' + WSP__ = mixin_comment(whitespace=r'[ \t]*\n?(?!\s*\n)[ \t]*', comment=r'%.*(?:\n|$)') + wspL__ = '' + wspR__ = WSP__ + par = RE('\\s*\\n\\s*\\n', wR='') + lf = RE('[ \\t]*\\n(?!\\s*\\n)', wR='') + wspc = RE('[ \\t]*\\n?(?!\\s*\\n)[ \\t]*', wR='') + chunk = RE('[^\\\\%$&\\{\\}\\[\\]\\s\\n]+', wR='') + brackets = RE('[\\[\\]]', wR='') + escaped = RE('\\\\[%$&]', wR='') + cfgtext = Alternative(chunk, wspc, escaped) + text = Alternative(cfgtext, brackets) + partext = Alternative(text, par) + block.set(Sequence(Token("{"), ZeroOrMore(Alternative(text, block)), Required(Token("}")))) + parblock.set(Sequence(Token("{"), ZeroOrMore(Alternative(partext, parblock)), Required(Token("}")))) + sequence = ZeroOrMore(Alternative(partext, parblock)) + config = Sequence(Token("["), cfgtext, Required(Token("]"))) + command = RE('\\\\\\w+', wR='') + genericcmd = Sequence(command, Optional(config), block) + name = Capture(RE('\\w+', wR='', wL=WSP__), "name") + endenv = Sequence(Token("\\end"), Required(Sequence(Token("{"), Pop(name), Token("}")))) + beginenv = Sequence(Token("\\begin"), Required(Sequence(Token("{"), name, Token("}")))) + genericenv = Sequence(beginenv, sequence, endenv) + root__ = genericenv + + +####################################################################### +# +# AST SECTION - Can be edited. Changes will be preserved. +# +####################################################################### + +LaTeX_ASTTransform = { + # AST Transformations for the LaTeX-grammar + "genericenv": no_operation, + "beginenv": no_operation, + "endenv": no_operation, + "name": no_operation, + "genericcmd": no_operation, + "command": no_operation, + "config": no_operation, + "sequence": no_operation, + "parblock": no_operation, + "block": no_operation, + "partext": no_operation, + "text": no_operation, + "cfgtext": no_operation, + "escaped": no_operation, + "brackets": no_operation, + "chunk": no_operation, + "wspc": no_operation, + "lf": no_operation, + "par": no_operation, + "": no_operation +} + +LaTeX_ASTPipeline = [LaTeX_ASTTransform] + + +####################################################################### +# +# COMPILER SECTION - Can be edited. Changes will be preserved. +# +####################################################################### + +class LaTeXCompiler(CompilerBase): + """Compiler for the abstract-syntax-tree of a LaTeX source file. + """ + + def __init__(self, grammar_name="LaTeX"): + super(LaTeXCompiler, self).__init__() + assert re.match('\w+\Z', grammar_name) + + def genericenv(self, node): + return node + + def beginenv(self, node): + pass + + def endenv(self, node): + pass + + def name(self, node): + pass + + def genericcmd(self, node): + pass + + def command(self, node): + pass + + def config(self, node): + pass + + def sequence(self, node): + pass + + def parblock(self, node): + pass + + def block(self, node): + pass + + def partext(self, node): + pass + + def text(self, node): + pass + + def cfgtext(self, node): + pass + + def escaped(self, node): + pass + + def brackets(self, node): + pass + + def chunk(self, node): + pass + + def wspc(self, node): + pass + + def lf(self, node): + pass + + def par(self, node): + pass + + +####################################################################### +# +# END OF DHPARSER-SECTIONS +# +####################################################################### + + +def compile_LaTeX(source): + """Compiles ``source`` and returns (result, errors, ast). + """ + return full_compilation(source, LaTeXScanner, + LaTeXGrammar(), LaTeX_ASTPipeline, LaTeXCompiler()) + +if __name__ == "__main__": + if len(sys.argv) > 1: + result, errors, ast = compile_LaTeX(sys.argv[1]) + if errors: + for error in errors: + print(error) + sys.exit(1) + else: + print(result) + else: + print("Usage: LaTeX_compiler.py [FILENAME]") -- GitLab