<commit_before>#Semantic Interpretation
Lets use the below grammar as an example. It describes parentheses wrapping a single character to an arbitrary depth.

    grammar ParenLanguage
      rule parenthesized_letter
        '(' parenthesized_letter ')'
        /
        [a-z]
      end
    end

Matches:

* `'a'`
* `'(a)'`
* `'((a))'`
* etc.


Output from a parser for this grammar looks like this:

![Tree Returned By ParenLanguageParser](./images/paren_language_output.png)

This is a parse tree whose nodes are instances of `Treetop::Runtime::SyntaxNode`. What if we could define methods on these node objects? We would then have an object-oriented program whose structure corresponded to the structure of our language. Treetop provides two techniques for doing just this.

##Associating Methods with Node-Instantiating Expressions
Sequences and all types of terminals are node-instantiating expressions. When they match, they create instances of `Treetop::Runtime::SyntaxNode`. Methods can be added to these nodes in the following ways:

###Inline Method Definition
Methods can be added to the nodes instantiated by the successful match of an expression

    grammar ParenLanguage
      rule parenthesized_letter
        '(' parenthesized_letter ')' {
          def depth
            parenthesized_letter.depth + 1
          end
        }
        /
        [a-z] {
          def depth
            0
          end
        }
      end
    end

Note that each alternative expression is followed by a block containing a method definition. A `depth` method is defined on both expressions. The recursive `depth` method defined in the block following the first expression determines the depth of the nested parentheses and adds one two it. The base case is implemented in the block following the second expression; a single character has a depth of 0.


###Custom `SyntaxNode` Subclass Declarations
You can instruct the parser to instantiate a custom subclass of Treetop::Runtime::SyntaxNode for an expression by following it by the name of that class enclosed in angle brackets (`<>`). The above inline method definitions could have been moved out into a single class like so.

    # in .treetop file
    grammar ParenLanguage
      rule parenthesized_letter
        '(' parenthesized_letter ')' <ParenNode>
        /
        [a-z] <ParenNode>
      end
    end

    # in separate .rb file
    class ParenNode < Treetop::Runtime::SyntaxNode
      def depth
        if nonterminal?
          parenthesized_letter.depth + 1
        else
          0<commit_msg>Fixed a typo in the documentation<commit_after>#Semantic Interpretation
Lets use the below grammar as an example. It describes parentheses wrapping a single character to an arbitrary depth.

    grammar ParenLanguage
      rule parenthesized_letter
        '(' parenthesized_letter ')'
        /
        [a-z]
      end
    end

Matches:

* `'a'`
* `'(a)'`
* `'((a))'`
* etc.


Output from a parser for this grammar looks like this:

![Tree Returned By ParenLanguageParser](./images/paren_language_output.png)

This is a parse tree whose nodes are instances of `Treetop::Runtime::SyntaxNode`. What if we could define methods on these node objects? We would then have an object-oriented program whose structure corresponded to the structure of our language. Treetop provides two techniques for doing just this.

##Associating Methods with Node-Instantiating Expressions
Sequences and all types of terminals are node-instantiating expressions. When they match, they create instances of `Treetop::Runtime::SyntaxNode`. Methods can be added to these nodes in the following ways:

###Inline Method Definition
Methods can be added to the nodes instantiated by the successful match of an expression

    grammar ParenLanguage
      rule parenthesized_letter
        '(' parenthesized_letter ')' {
          def depth
            parenthesized_letter.depth + 1
          end
        }
        /
        [a-z] {
          def depth
            0
          end
        }
      end
    end

Note that each alternative expression is followed by a block containing a method definition. A `depth` method is defined on both expressions. The recursive `depth` method defined in the block following the first expression determines the depth of the nested parentheses and adds one to it. The base case is implemented in the block following the second expression; a single character has a depth of 0.


###Custom `SyntaxNode` Subclass Declarations
You can instruct the parser to instantiate a custom subclass of Treetop::Runtime::SyntaxNode for an expression by following it by the name of that class enclosed in angle brackets (`<>`). The above inline method definitions could have been moved out into a single class like so.

    # in .treetop file
    grammar ParenLanguage
      rule parenthesized_letter
        '(' parenthesized_letter ')' <ParenNode>
        /
        [a-z] <ParenNode>
      end
    end

    # in separate .rb file
    class ParenNode < Treetop::Runtime::SyntaxNode
      def depth
        if nonterminal?
          parenthesized_letter.depth + 1
        else
          0
{'fraction_non_alphanumeric': 0.05686465433300876, 'fraction_numerical': 0.0019474196689386564, 'mean_word_length': 3.0125, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4211269', 'n_tokens_mistral': 1333, 'n_tokens_neox': 1268, 'n_words': 610}