Ejemplo n.º 1
0
    def test_unmatchedProgramCompletionAtMiddle(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                match: // {
                    scope: comment.line.start.sma
                }
                match: single {
                    scope: comment.middle.start.sma
                }
            }
        """ )

        example_program = wrap_text(
        r"""
            // Example single line commentary
        """ )

        example_theme = \
        {
            "comment" : "#FF0000",
        }

        generated_html = self._getBackend(example_grammar, example_program, example_theme)

        self.assertTextEqual(
        r"""
            + <!DOCTYPE html><html><head><title>Abstract Machine Language - source.sma</title></head>
            + <body style="white-space: pre; font-family: monospace;"><font color="#FF0000" grammar_scope="comment.line.start.sma" theme_scope="comment">//</font><span grammar_scope="none" theme_scope="none"> Example </span><font color="#FF0000" grammar_scope="comment.middle.start.sma" theme_scope="comment">single</font><span grammar_scope="none" theme_scope="none"> line commentary</span></body></html>
        """, generated_html )
Ejemplo n.º 2
0
    def test_simpleMatchStamement(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                match: (true|false) {
                    scope: boolean.sma
                }
            }
        """ )

        example_program = wrap_text(
        r"""true""" )

        example_theme = \
        {
            "boolean" : "#FF0000",
        }

        generated_html = self._getBackend(example_grammar, example_program, example_theme)

        self.assertTextEqual(
        r"""
            + <!DOCTYPE html><html><head><title>Abstract Machine Language - source.sma</title></head>
            + <body style="white-space: pre; font-family: monospace;"><font color="#FF0000" grammar_scope="boolean.sma" theme_scope="boolean">true</font></body></html>
        """, generated_html )
Ejemplo n.º 3
0
    def test_singleIfStamement(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                match: if\( {
                    scope: if.statement.definition
                    push: {
                        meta_scope: if.statement.body
                        match: \) {
                            scope: if.statement.definition
                            pop: true
                        }
                    }
                }
            }
        """ )

        example_program = wrap_text(
        r"""if(something) bar""" )

        example_settings = {
            "if.statement.body" : 2,
        }

        generated_html = self._getBackend(example_grammar, example_program, example_settings)

        self.assertTextEqual(
        r"""
            + <!DOCTYPE html><html><head><title>Abstract Machine Language - source.sma</title></head>
            + <body style="white-space: pre; font-family: monospace;"><span setting="unformatted" grammar_scope="if.statement.definition" setting_scope="" original_program="if(">if(</span><span setting="2" grammar_scope="if.statement.body" setting_scope="if.statement.body" original_program="something">  something  </span><span setting="unformatted" grammar_scope="if.statement.definition" setting_scope="" original_program=")">)</span><span grammar_scope="none" setting_scope="none"> bar</span></body></html>
        """, generated_html )
Ejemplo n.º 4
0
    def test_duplicatedIncludes(self):
        example_grammar = wrap_text(
        r"""
            name: Abstract Machine Language
            scope: source.sma
            contexts: {
                match: (true|false) {
                    scope: constant.language
                }
                include: duplicate
            }

            duplicate: {
                match: (true|false) {
                    scope: constant.language
                }
            }

            duplicate: {
                match: (true|false) {
                    scope: constant.language
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Duplicated include `duplicate` defined in your grammar on [@-1,234:242='duplicate'<__ANON_1>,16:1]
        """, error.exception )
Ejemplo n.º 5
0
    def test_constantUsage(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            $constant:  test
            contexts: {
                    match: (true$constant:|false)$constant: {
                }
            }
        """ )
        tree = self._getError( example_grammar, True )

        self.assertTextEqual(
        r"""
            + language_syntax
            +   preamble_statements
            +     master_scope_name_statement  source.sma
            +     target_language_name_statement  Abstract Machine Language
            +      test
            +   language_construct_rules
            +     indentation_block
            +       statements_list
            +         match_statement  (true test|false) test
        """, tree.pretty(debug=0) )
Ejemplo n.º 6
0
    def test_usingConstOutOfBlockDefinition(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                $constant: test:
                match: (true $constant:|false) {
                    include: block
                }
            }

            block: {
                match: ($constant:) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Using constant `$constant:` out of block on
            +    [@-1,173:182='$constant:'<CONSTANT_USAGE_>,11:13] from
            +    [@-1,66:75='$constant:'<CONSTANT_NAME_>,4:5]
        """, error.exception )
Ejemplo n.º 7
0
    def _getError(self, example_grammar, return_tree=False, log_level=0):
        example_grammar = wrap_text( example_grammar )

        my_parser = self._getParser(log_level)
        tree = my_parser.parse(example_grammar)

        # function_file = get_relative_path( "examples/%s.png" % getCallerName(), __file__ )
        # from utilities import make_png
        # make_png( tree, get_relative_path( function_file, __file__ ) )

        # https://stackoverflow.com/questions/5067604/determine-function-name-from-within-that-function-without-using-traceback
        # import inspect
        # log( 1, "%s", getCallerName() )
        # log( 1, "%s", inspect.stack()[1][3] )

        if return_tree:
            new_tree = semantic_analyzer.TreeTransformer().transform( tree )

            # log( 1, 'tree: \n%s', tree.pretty() )
            # log( 1, 'tree: \n%s', new_tree.pretty() )
            return new_tree

        else:
            with self.assertRaises( semantic_analyzer.SemanticErrors ) as error:
                new_tree = semantic_analyzer.TreeTransformer().transform( tree )

            return error
Ejemplo n.º 8
0
    def test_simplePushPopStatement(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                match: // {
                    scope: comment.start.sma
                    push: {
                        meta_scope: comment.line.sma
                        match: \n|\$ {
                            pop: true
                        }
                    }
                }
            }
        """ )

        example_program = wrap_text(
        r"""
            // Example single line commentary
        """ )

        example_theme = \
        {
            "comment" : "#FF0000",
            "comment.line" : "#00FF00",
        }

        generated_html = self._getBackend( example_grammar, example_program, example_theme )

        self.assertTextEqual(
        r"""
            + <!DOCTYPE html><html><head><title>Abstract Machine Language - source.sma</title></head>
            + <body style="white-space: pre; font-family: monospace;"><font color="#FF0000" grammar_scope="comment.start.sma" theme_scope="comment">//</font><font color="#00FF00" grammar_scope="comment.line.sma" theme_scope="comment.line"> Example single line commentary</font></body></html>
        """, generated_html )
Ejemplo n.º 9
0
    def test_missingNameGlobal(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            contexts: {
                    match: (true|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Missing target language name in your grammar preamble.
        """, error.exception )
Ejemplo n.º 10
0
    def test_missingScopeGlobalName(self):
        example_grammar = wrap_text(
        r"""
            name: Abstract Machine Language
            contexts: {
                    match: (true|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Missing master scope name in your grammar preamble.
        """, error.exception )
Ejemplo n.º 11
0
    def test_invalidRegexInput(self):
        example_grammar = wrap_text(
        r"""
            name: Abstract Machine Language
            scope: source.sma
            contexts: {
                match: (true|false {
                    scope: constant.language
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Invalid regular expression `(true|false` on match statement: missing ), unterminated subpattern at position 0
        """, error.exception )
Ejemplo n.º 12
0
    def test_redifinedConst(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            $constant: test
            contexts: {
                $constant: test
                    match: (true$constant:|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Constant redefinition on [@-1,82:91='$constant:'<CONSTANT_NAME_>,5:5]
        """, error.exception )
Ejemplo n.º 13
0
    def test_missingIncludeDetection(self):
        example_grammar = wrap_text(
        r"""
            name: Abstract Machine Language
            scope: source.sma
            contexts: {
                match: (true|false) {
                    scope: constant.language
                }
                include: missing_include
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Missing include `missing_include` defined in your grammar on [@-1,140:154='missing_include'<TEXT_CHUNK_END_>,7:14]
        """, error.exception )
Ejemplo n.º 14
0
    def test_recursiveConstantDefinition(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            $constant:  test$constant:
            contexts: {
                    match: (true$constant:|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            +   Warnings:
            + 1. Recursive constant definition on [@-1,50:59='$constant:'<CONSTANT_NAME_>,3:1]
        """, error.exception )
Ejemplo n.º 15
0
    def test_unsusedConstantDeclaration(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            $constant: test
            contexts: {
                    match: (true|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            +   Warnings:
            + 1. Unused constant `$constant:` defined in your grammar on [@-1,50:59='$constant:'<CONSTANT_NAME_>,3:1]
        """, error.exception )
Ejemplo n.º 16
0
    def test_usingConstOutOfScope(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                    match: (true$constant:|false) {
                }
                $constant: test
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Using constant `$constant:` out of scope on
            +    [@-1,82:91='$constant:'<CONSTANT_USAGE_>,4:21] from
            +    [@-1,112:121='$constant:'<CONSTANT_NAME_>,6:5]
        """, error.exception )
Ejemplo n.º 17
0
    def test_duplicatedGlobalNames(self):
        example_grammar = wrap_text(
        r"""
            name: Abstract Machine Language
            name: Abstract Machine Language
            scope: source.sma
            scope: source.sma
            contexts: {
                    match: (true|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Duplicated target language name defined in your grammar on [@-1,38:62='Abstract Machine Language'<TEXT_CHUNK_END_>,2:7]
            + 2. Duplicated master scope name defined in your grammar on [@-1,89:98='source.sma'<TEXT_CHUNK_END_>,4:8]
        """, error.exception )
Ejemplo n.º 18
0
    def test_unsusedInclude(self):
        example_grammar = wrap_text(
        r"""
            scope: source.sma
            name: Abstract Machine Language
            contexts: {
                    match: (true|false) {
                }
            }

            unused: {
                    match: (true|false) {
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            +   Warnings:
            + 1. Unused include `unused` defined in your grammar on [@-1,101:106='unused'<__ANON_1>,8:1]
        """, error.exception )
Ejemplo n.º 19
0
    def test_duplicatedContext(self):
        example_grammar = wrap_text(
        r"""
            name: Abstract Machine Language
            scope: source.sma
            contexts: {
                match: (true|false) {
                    scope: constant.language
                }
            }

            contexts: {
                match: (true|false) {
                    scope: constant.language
                }
            }
        """ )
        error = self._getError( example_grammar )

        self.assertTextEqual(
        r"""
            + 1. Extra `contexts` rule defined in your grammar on [@-1,130:137='contexts'<__ANON_1>,9:1]
        """, error.exception )
Ejemplo n.º 20
0
    def test_complexGrammarFile(self):
        example_grammar = wrap_text(
        r"""
        scope: source.sma
        name: Abstract Machine Language
        contexts: {
            include: pawn_keywords
            include: pawn_comment
            include: pawn_boolean
            include: pawn_preprocessor
            include: pawn_string
            include: pawn_function
            include: pawn_numbers
        }
        pawn_boolean: {
            match: (true|false) {
                scope: boolean.sma
            }
        }
        pawn_comment: {
            match: /\* {
                scope: comment.begin.sma
                push: {
                    meta_scope: comment.sma
                    match: \*/ {
                        pop: true
                    }
                }
            }
            match: // {
                push: {
                    meta_scope: comment.documentation.sma
                    match: \n {
                        pop: true
                    }
                }
            }
        }
        pawn_preprocessor: {
            match: \s*#define {
                scope: function.definition.sma
                push: {
                    meta_scope: meta.preprocessor.sma
                    match: \n {
                        pop: true
                    }
                }
            }
        }
        pawn_string: {
            match: "(?=.*") {
                scope: punctuation.definition.string.begin.sma
                push: {
                    meta_scope: string.quoted.double.sma
                    match: "(?!.*") {
                        scope: punctuation.definition.string.end.sma
                        pop: true
                    }
                }
            }
        }
        pawn_function: {
            match: (\w+)\s*(\(.*\)) {
                scope: function.call.sma
            }
        }
        pawn_numbers: {
            match: \d+\.?\d* {
                scope: constant.numeric.sma
            }
        }
        pawn_keywords: {
            match: \b(sizeof|charsmax|assert|break|case|continue|default|do|in|else|exit|for|goto|if|return|switch|while)\b {
                scope: keyword.control.sma
            }
            match: \b(var|new)\b {
                scope: keyword.new.sma
            }
        }
        """ )

        example_program = wrap_text(
        r"""
            /* Commentary example */ true or false
            #define GLOBAL_CONSTANT
            var string = "My string definition"
            void function() {

                // Single line commmentary
                var number = 100.0
                for var index = 5999; index < sizeof number; ++index:

                    /* More multiline
                       comments
                       with a bunch of
                       lines */
                    for variable in list:
                        print( variable )
                }

                #define MORE_CRAZYNESS 100000
                if index == 0:
                    // More singleline comments
                    // with incredicle single linearity
                    var string = "Cool beatiful String"

                    while string in list:
                        exit( string )
                }
            }
        """ )

        example_theme = \
        {
            "boolean" : "#FF0000",
            "comment" : "#00FF00",
            "function" : "#DDB700",
            "keyword.new" : "#FF00FF",
            "meta" : "#0000FF",
            "storage" : "#8000FF",
            "string" : "#808080",
            "punctuation" : "#FF0000",
            "constant" : "#99CC99",
            "keyword" : "#804000",
            "comment.documentation" : "#248591",
        }

        generated_html = self._getBackend(example_grammar, example_program, example_theme)

        self.assertTextEqual(
        r"""
            + <!DOCTYPE html><html><head><title>Abstract Machine Language - source.sma</title></head>
            + <body style="white-space: pre; font-family: monospace;"><font color="#00FF00" grammar_scope="comment.begin.sma" theme_scope="comment">/*</font><font color="#00FF00" grammar_scope="comment.sma" theme_scope="comment"> Commentary example */</font><span grammar_scope="none" theme_scope="none"> </span><font color="#FF0000" grammar_scope="boolean.sma" theme_scope="boolean">true</font><span grammar_scope="none" theme_scope="none"> or </span><font color="#FF0000" grammar_scope="boolean.sma" theme_scope="boolean">false</font><font color="#DDB700" grammar_scope="function.definition.sma" theme_scope="function"><br />#define</font><font color="#0000FF" grammar_scope="meta.preprocessor.sma" theme_scope="meta"> GLOBAL_CONSTANT<br /></font><font color="#FF00FF" grammar_scope="keyword.new.sma" theme_scope="keyword.new">var</font><span grammar_scope="none" theme_scope="none"> string = </span><font color="#FF0000" grammar_scope="punctuation.definition.string.begin.sma" theme_scope="punctuation">"</font><font color="#808080" grammar_scope="string.quoted.double.sma" theme_scope="string">My string definition</font><font color="#FF0000" grammar_scope="punctuation.definition.string.end.sma" theme_scope="punctuation">"</font><span grammar_scope="none" theme_scope="none"><br />void </span><font color="#DDB700" grammar_scope="function.call.sma" theme_scope="function">function()</font><span grammar_scope="none" theme_scope="none"> {<br /><br />    //</span><font color="#248591" grammar_scope="comment.documentation.sma" theme_scope="comment.documentation"> Single line commmentary<br /></font><span grammar_scope="none" theme_scope="none">    </span><font color="#FF00FF" grammar_scope="keyword.new.sma" theme_scope="keyword.new">var</font><span grammar_scope="none" theme_scope="none"> number = </span><font """

            # Break this unit test result into two parts otherwise Latex cannot including this file: `Dimension too large`
            + r"""color="#99CC99" grammar_scope="constant.numeric.sma" theme_scope="constant">100.0</font><span grammar_scope="none" theme_scope="none"><br />    </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">for</font><span grammar_scope="none" theme_scope="none"> </span><font color="#FF00FF" grammar_scope="keyword.new.sma" theme_scope="keyword.new">var</font><span grammar_scope="none" theme_scope="none"> index = </span><font color="#99CC99" grammar_scope="constant.numeric.sma" theme_scope="constant">5999</font><span grammar_scope="none" theme_scope="none">; index &lt; </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">sizeof</font><span grammar_scope="none" theme_scope="none"> number; ++index:<br /><br />        </span><font color="#00FF00" grammar_scope="comment.begin.sma" theme_scope="comment">/*</font><font color="#00FF00" grammar_scope="comment.sma" theme_scope="comment"> More multiline<br />           comments<br />           with a bunch of<br />           lines */</font><span grammar_scope="none" theme_scope="none"><br />        </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">for</font><span grammar_scope="none" theme_scope="none"> variable </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">in</font><span grammar_scope="none" theme_scope="none"> list:<br />            </span><font color="#DDB700" grammar_scope="function.call.sma" theme_scope="function">print( variable )</font><span grammar_scope="none" theme_scope="none"><br />    }</span><font color="#DDB700" grammar_scope="function.definition.sma" theme_scope="function"><br /><br />    #define</font><font color="#0000FF" grammar_scope="meta.preprocessor.sma" theme_scope="meta"> MORE_CRAZYNESS 100000<br /></font><span grammar_scope="none" theme_scope="none">    </span><font """

            # Break this unit test result into two parts otherwise Latex cannot including this file: `Dimension too large`
            + r"""color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">if</font><span grammar_scope="none" theme_scope="none"> index == </span><font color="#99CC99" grammar_scope="constant.numeric.sma" theme_scope="constant">0</font><span grammar_scope="none" theme_scope="none">:<br />        //</span><font color="#248591" grammar_scope="comment.documentation.sma" theme_scope="comment.documentation"> More singleline comments<br /></font><span grammar_scope="none" theme_scope="none">        //</span><font color="#248591" grammar_scope="comment.documentation.sma" theme_scope="comment.documentation"> with incredicle single linearity<br /></font><span grammar_scope="none" theme_scope="none">        </span><font color="#FF00FF" grammar_scope="keyword.new.sma" theme_scope="keyword.new">var</font><span grammar_scope="none" theme_scope="none"> string = </span><font color="#FF0000" grammar_scope="punctuation.definition.string.begin.sma" theme_scope="punctuation">"</font><font color="#808080" grammar_scope="string.quoted.double.sma" theme_scope="string">Cool beatiful String</font><font color="#FF0000" grammar_scope="punctuation.definition.string.end.sma" theme_scope="punctuation">"</font><span grammar_scope="none" theme_scope="none"><br /><br />        </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">while</font><span grammar_scope="none" theme_scope="none"> string </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">in</font><span grammar_scope="none" theme_scope="none"> list:<br />            </span><font color="#804000" grammar_scope="keyword.control.sma" theme_scope="keyword">exit</font><span grammar_scope="none" theme_scope="none">( string )<br />    }<br />}</span></body></html>
        """, generated_html )
Ejemplo n.º 21
0
## The parser used to build the syntax tree and parse the input text
with open(metagrammar_path, "r", encoding='utf-8') as file:
    my_parser = Lark(file.read(),
                     start='language_syntax',
                     parser='lalr',
                     lexer='contextual')

example_grammar = wrap_text(r"""
    scope: source.sma
    name: Abstract Machine Language
    contexts: {
        match: // {
            scope: comment.start.sma
            push: {
                meta_scope: comment.line.sma
                match: \n|\$ {
                    pop: true
                }
            }
        }
    }
""")


def generate_image(tree, tree_name):
    log.clean("Generating '%s'...", tree_name)
    make_png(tree, get_relative_path(tree_name, __file__), debug=0, dpi=300)


syntax_tree = my_parser.parse(example_grammar)
Ejemplo n.º 22
0
## The parser used to build the syntax tree and parse the input text
with open(metagrammar_path, "r", encoding='utf-8') as file:
    my_parser = Lark(file.read(),
                     start='language_syntax',
                     parser='lalr',
                     lexer='contextual')

example_grammar = wrap_text(r"""
    scope: source.sma
    name: Abstract Machine Language
    contexts: {
        match: if\( {
            scope: if.statement.definition
            push: {
                meta_scope: if.statement.body
                match: \) {
                    scope: if.statement.definition
                    pop: true
                }
            }
        }
    }
""")


def generate_image(tree, tree_name):
    log.clean("Generating '%s'...", tree_name)
    make_png(tree, get_relative_path(tree_name, __file__), debug=0, dpi=300)


syntax_tree = my_parser.parse(example_grammar)