test_parsers.py 3.76 KB
Newer Older
1 2
#!/usr/bin/python3

3
"""test_parsers.py - tests of the parsers-module of DHParser 
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Author: Eckhart Arnold <arnold@badw.de>

Copyright 2017 Bavarian Academy of Sciences and Humanities

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import os
import sys

sys.path.append(os.path.abspath('../../'))
26
from DHParser.toolkit import compile_python_object
27
from DHParser.parsers import full_compilation
28
from DHParser.ebnf import EBNFGrammar, EBNFTransform, EBNFCompiler
29
from DHParser.dsl import compileEBNF, DHPARSER_IMPORTS
30 31 32 33

WRITE_LOGS = True


34
class TestInfiLoopsAndRecursion:
35
    def test_direct_left_recursion(self):
36 37 38 39 40 41 42 43
        minilang = """
            @ whitespace = linefeed
            formula = [ //~ ] expr
            expr = expr ("+"|"-") term | term
            term = term ("*"|"/") factor | factor
            factor = /[0-9]+/~
            # example:  "5 + 3 * 4"
            """
44
        snippet = "5 + 3 * 4"
45 46 47
        parser = compileEBNF(minilang)()
        assert parser
        syntax_tree = parser.parse(snippet)
48
        assert not syntax_tree.collect_errors()
49
        assert snippet == str(syntax_tree)
50 51
        if WRITE_LOGS:
            syntax_tree.log("test_LeftRecursion_direct", '.cst')
Eckhart Arnold's avatar
Eckhart Arnold committed
52
            # self.minilang_parser1.log_parsing_history("test_LeftRecursion_direct")
53 54 55 56

    def test_indirect_left_recursion(self):
        pass

57 58 59 60 61 62 63 64
    def test_inifinite_loops(self):
        minilang = """not_forever = { // } \n"""
        snippet = " "
        parser = compileEBNF(minilang)()
        syntax_tree = parser.parse(snippet)
        assert syntax_tree.error_flag
        # print(syntax_tree.collect_errors())

65

66 67 68 69 70 71 72
class TestRegex:
    def test_multilineRegex(self):
        mlregex = r"""
        regex =  /\w+    # one or more alphabetical characters including the underscore
                  [+]    # followed by a plus sign
                  \w*    # possibly followed by more alpha chracters/
        """
73
        result, messages, syntax_tree = full_compilation(mlregex, None,
74
                                                         EBNFGrammar(), EBNFTransform,
75
                                                         EBNFCompiler('MultilineRegexTest'))
76
        assert result
77 78 79 80 81 82 83
        assert not messages
        parser = compile_python_object(DHPARSER_IMPORTS + result, '\w+Grammar$')()
        node, rest = parser.regex('abc+def')
        assert rest == ''
        assert node.parser.name == "regex"
        assert str(node) == 'abc+def'

84 85 86 87 88 89 90 91 92 93 94 95 96
    def test_token(self):
        tokenlang = r"""
            @whitespace = linefeed
            lang        = "" begin_token {/\w+/ ""} end_token
            begin_token = "\begin{document}"
            end_token   = "\end{document}"
            """
        testdoc = r"""
            \begin{document}
            test
            \end{document}
            """
        result, messages, syntax_tree = full_compilation(tokenlang, None,
97
                                                         EBNFGrammar(), EBNFTransform, EBNFCompiler("TokenTest"))
98 99 100 101 102 103 104
        assert result
        assert not messages
        parser = compile_python_object(DHPARSER_IMPORTS + result, '\w+Grammar$')()
        result = parser.parse(testdoc)
        # parser.log_parsing_history("test.log")
        assert not result.error_flag

105

106
if __name__ == "__main__":
107
    from run import runner
108
    runner("TestInfiLoopsAndRecursion", globals())