#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# CAVEAT UTILITOR
# This file was automatically generated by Grako.
#    https://bitbucket.org/apalala/grako/
# Any changes you make to it will be overwritten the
# next time the file is generated.
#

from __future__ import print_function, division, absolute_import, unicode_literals
from grako.parsing import * # noqa
from grako.exceptions import * # noqa


__version__ = '14.160.22.15.56'


class ModelicaParser(Parser):
    def __init__(self, whitespace=None, **kwargs):
        super(ModelicaParser, self).__init__(whitespace=whitespace, **kwargs)

    @rule_def
    def _stored_definition_(self):
        with self._optional():
            self._within_()
            with self._optional():
                self._name_()
            self._token(';')
        def block0():
            with self._optional():
                self._final_()
            self._class_definition_()
            self._token(';')
        self._closure(block0)

    @rule_def
    def _class_definition_(self):
        with self._optional():
            self._encapsulated_()
        self._class_prefixes_()
        self._class_specifier_()

    @rule_def
    def _class_prefixes_(self):
        with self._optional():
            self._partial_()
        with self._group():
            with self._choice():
                with self._option():
                    self._class_()
                with self._option():
                    self._model_()
                with self._option():
                    with self._optional():
                        self._operator_()
                    self._record_()
                with self._option():
                    self._block_()
                with self._option():
                    with self._optional():
                        self._expandable_()
                    self._connector_()
                with self._option():
                    self._type_()
                with self._option():
                    self._package_()
                with self._option():
                    with self._optional():
                        with self._group():
                            with self._choice():
                                with self._option():
                                    self._pure_()
                                with self._option():
                                    self._impure_()
                                self._error('no available options')
                    with self._optional():
                        self._operator_()
                    self._function_()
                with self._option():
                    self._operator_()
                self._error('no available options')

    @rule_def
    def _class_specifier_(self):
        self._IDENT_()
        with self._optional():
            self._string_comment_()
        self._composition_()
        self._end_()
        self._IDENT_()

    @rule_def
    def _base_prefix_(self):
        self._type_prefix_()

    @rule_def
    def _enum_list_(self):
        self._enumeration_literal_()
        def block0():
            self._token(',')
            self._enumeration_literal_()
        self._closure(block0)

    @rule_def
    def _enumeration_literal_(self):
        self._IDENT_()
        self._comment_()

    @rule_def
    def _composition_(self):
        self._element_list_()

    @rule_def
    def _language_specification_(self):
        self._STRING_()

    @rule_def
    def _external_function_call_(self):
        with self._optional():
            self._component_reference_()
            self._token('=')
        self._IDENT_()
        self._token('(')
        with self._optional():
            self._expression_list_()
        self._token(')')

    @rule_def
    def _element_list_(self):
        def block0():
            self._element_()
            self._token(';')
        self._closure(block0)

    @rule_def
    def _element_(self):
        self._component_clause_()

    @rule_def
    def _import_clause_(self):
        self._import_()
        with self._group():
            with self._choice():
                with self._option():
                    self._IDENT_()
                    self._token('=')
                    self._name_()
                with self._option():
                    self._name_()
                    with self._optional():
                        self._token('.')
                        with self._group():
                            with self._choice():
                                with self._option():
                                    self._token('*')
                                with self._option():
                                    self._token('{')
                                    self._import_list_()
                                    self._token('}')
                                self._error('expecting one of: *')
                self._error('no available options')
        self._comment_()

    @rule_def
    def _import_list_(self):
        self._IDENT_()
        with self._optional():
            self._token(',')
            self._import_list_()

    @rule_def
    def _extends_clause_(self):
        self._extends_()
        self._name_()
        with self._optional():
            self._class_modification_()
        with self._optional():
            self._annotation_()

    @rule_def
    def _constraining_clause_(self):
        self._constrainedby_()
        self._name_()
        with self._optional():
            self._class_modification_()

    @rule_def
    def _component_clause_(self):
        self._type_prefix_()
        self._IDENT_()

    @rule_def
    def _type_prefix_(self):
        with self._optional():
            with self._choice():
                with self._option():
                    self._flow_()
                with self._option():
                    self._stream_()
                self._error('no available options')
        with self._optional():
            with self._choice():
                with self._option():
                    self._discrete_()
                with self._option():
                    self._parameter_()
                with self._option():
                    self._constant_()
                self._error('no available options')
        with self._optional():
            with self._choice():
                with self._option():
                    self._input_()
                with self._option():
                    self._output_()
                self._error('no available options')

    @rule_def
    def _type_specifier_(self):
        self._IDENT_()

    @rule_def
    def _component_list_(self):
        self._component_declaration_()
        def block0():
            self._token(',')
            self._component_declaration_()
        self._closure(block0)

    @rule_def
    def _component_declaration_(self):
        self._declaration_()
        with self._optional():
            self._condition_attribute_()
        self._comment_()

    @rule_def
    def _condition_attribute_(self):
        self._if_()
        self._expression_()

    @rule_def
    def _declaration_(self):
        self._IDENT_()
        with self._optional():
            self._array_subscripts_()
        with self._optional():
            self._modification_()

    @rule_def
    def _modification_(self):
        with self._choice():
            with self._option():
                self._class_modification_()
                with self._optional():
                    self._token('=')
                    self._expression_()
            with self._option():
                self._token('=')
                self._expression_()
            with self._option():
                self._token(':=')
                self._expression_()
            self._error('no available options')

    @rule_def
    def _class_modification_(self):
        self._token('(')
        with self._optional():
            self._argument_list_()
        self._token(')')

    @rule_def
    def _argument_list_(self):
        self._argument_()
        def block0():
            self._token(',')
            self._argument_()
        self._closure(block0)

    @rule_def
    def _argument_(self):
        with self._choice():
            with self._option():
                self._element_modification_or_replaceable_()
            with self._option():
                self._element_redeclaration_()
            self._error('no available options')

    @rule_def
    def _element_modification_or_replaceable_(self):
        with self._optional():
            self._each_()
        with self._optional():
            self._final_()
        with self._group():
            with self._choice():
                with self._option():
                    self._element_modification_()
                with self._option():
                    self._element_replaceable_()
                self._error('no available options')

    @rule_def
    def _element_modification_(self):
        self._name_()
        with self._optional():
            self._modification_()
        self._string_comment_()

    @rule_def
    def _element_redeclaration_(self):
        self._redeclare_()
        with self._optional():
            self._each_()
        with self._optional():
            self._final_()
        with self._group():
            with self._choice():
                with self._option():
                    with self._group():
                        with self._choice():
                            with self._option():
                                self._short_class_definition_()
                            with self._option():
                                self._component_clause1_()
                            self._error('no available options')
                with self._option():
                    self._element_replaceable_()
                self._error('no available options')

    @rule_def
    def _element_replaceable_(self):
        self._replaceable_()
        with self._group():
            with self._choice():
                with self._option():
                    self._short_class_definition_()
                with self._option():
                    self._component_clause1_()
                self._error('no available options')
        with self._optional():
            self._constraining_clause_()

    @rule_def
    def _component_clause1_(self):
        self._type_prefix_()
        self._type_specifier_()
        self._component_declaration1_()

    @rule_def
    def _component_declaration1_(self):
        self._declaration_()
        self._comment_()

    @rule_def
    def _short_class_definition_(self):
        self._class_prefixes_()
        self._IDENT_()
        self._token('=')
        with self._group():
            with self._choice():
                with self._option():
                    self._base_prefix_()
                    self._name_()
                    with self._optional():
                        self._array_subscripts_()
                    with self._optional():
                        self._class_modification_()
                    self._comment_()
                with self._option():
                    self._enumeration_()
                    self._token('(')
                    with self._group():
                        with self._choice():
                            with self._option():
                                with self._optional():
                                    self._enum_list_()
                            with self._option():
                                self._token(':')
                            self._error('expecting one of: :')
                    self._token(')')
                    self._comment_()
                self._error('no available options')

    @rule_def
    def _equation_section_(self):
        with self._optional():
            self._initial_()
        self._equation_()
        def block0():
            self._equation_()
            self._token(';')
        self._closure(block0)

    @rule_def
    def _algorithm_section_(self):
        with self._optional():
            self._initial_()
        self._algorithm_()
        def block0():
            self._statement_()
            self._token(';')
        self._closure(block0)

    @rule_def
    def _equation_(self):
        with self._choice():
            with self._option():
                with self._group():
                    with self._choice():
                        with self._option():
                            self._simple_expression_()
                            self._token('=')
                            self._expression_()
                        with self._option():
                            self._if_equation_()
                        with self._option():
                            self._for_equation_()
                        with self._option():
                            self._connect_clause_()
                        with self._option():
                            self._when_equation_()
                        with self._option():
                            self._name_()
                            self._function_call_args_()
                        self._error('no available options')
                self._comment_()
            with self._option():
                self._token('equation')
            self._error('expecting one of: equation')

    @rule_def
    def _statement_(self):
        with self._group():
            with self._choice():
                with self._option():
                    self._component_reference_()
                    with self._group():
                        with self._choice():
                            with self._option():
                                self._token(':=')
                                self._expression_()
                            with self._option():
                                self._function_call_args_()
                            self._error('no available options')
                with self._option():
                    self._token('(')
                    self._output_expression_list_()
                    self._token(')')
                    self._token(':=')
                    self._component_reference_()
                    self._function_call_args_()
                with self._option():
                    self._break_()
                with self._option():
                    self._return_()
                with self._option():
                    self._if_statement_()
                with self._option():
                    self._for_statement_()
                with self._option():
                    self._while_statement_()
                with self._option():
                    self._when_statement_()
                self._error('no available options')
        self._comment_()

    @rule_def
    def _if_equation_(self):
        self._if_()
        self._expression_()
        self._then_()
        def block0():
            self._equation_()
            self._token(';')
        self._closure(block0)
        def block1():
            self._elseif_()
            self._expression_()
            self._then_()
            def block2():
                self._equation_()
                self._token(';')
            self._closure(block2)
        self._closure(block1)
        with self._optional():
            self._else_()
            def block3():
                self._equation_()
                self._token(';')
            self._closure(block3)
        self._end_()
        self._if_()

    @rule_def
    def _if_statement_(self):
        self._if_()
        self._expression_()
        self._then_()
        def block0():
            self._statement_()
            self._token(';')
        self._closure(block0)
        def block1():
            self._elseif_()
            self._expression_()
            self._then_()
            def block2():
                self._statement_()
                self._token(';')
            self._closure(block2)
        self._closure(block1)
        with self._optional():
            self._else_()
            def block3():
                self._statement_()
                self._token(';')
            self._closure(block3)
        self._end_()
        self._if_()

    @rule_def
    def _for_equation_(self):
        self._for_()
        self._for_indices_()
        self._loop_()
        def block0():
            self._equation_()
            self._token(';')
        self._closure(block0)
        self._end_()
        self._for_()

    @rule_def
    def _for_statement_(self):
        self._for_()
        self._for_indices_()
        self._loop_()
        def block0():
            self._statement_()
            self._token(';')
        self._closure(block0)
        self._end_()
        self._for_()

    @rule_def
    def _for_indices_(self):
        self._for_index_()
        def block0():
            self._token(',')
            self._for_index_()
        self._closure(block0)

    @rule_def
    def _for_index_(self):
        self._IDENT_()
        with self._optional():
            self._in_()
            self._expression_()

    @rule_def
    def _while_statement_(self):
        self._while_()
        self._expression_()
        self._loop_()
        def block0():
            self._statement_()
            self._token(';')
        self._closure(block0)
        self._end_()
        self._while_()

    @rule_def
    def _when_equation_(self):
        self._when_()
        self._expression_()
        self._then_()
        def block0():
            self._equation_()
            self._token(';')
        self._closure(block0)
        def block1():
            self._elsewhen_()
            self._expression_()
            self._then_()
            def block2():
                self._equation_()
                self._token(';')
            self._closure(block2)
        self._closure(block1)
        self._end_()
        self._when_()

    @rule_def
    def _when_statement_(self):
        self._when_()
        self._expression_()
        self._then_()
        def block0():
            self._statement_()
            self._token(';')
        self._closure(block0)
        def block1():
            self._elsewhen_()
            self._expression_()
            self._then_()
            def block2():
                self._statement_()
                self._token(';')
            self._closure(block2)
        self._closure(block1)
        self._end_()
        self._when_()

    @rule_def
    def _connect_clause_(self):
        self._connect_()
        self._token('(')
        self._component_reference_()
        self._token(',')
        self._component_reference_()
        self._token(')')

    @rule_def
    def _expression_(self):
        with self._choice():
            with self._option():
                self._simple_expression_()
            with self._option():
                self._if_()
                self._expression_()
                self._then_()
                self._expression_()
                def block0():
                    self._elseif_()
                    self._expression_()
                    self._then_()
                    self._expression_()
                self._closure(block0)
                self._else_()
                self._expression_()
            self._error('no available options')

    @rule_def
    def _simple_expression_(self):
        self._logical_expression_()
        with self._optional():
            self._token(':')
            self._logical_expression_()
            with self._optional():
                self._token(':')
                self._logical_expression_()

    @rule_def
    def _logical_expression_(self):
        self._logical_term_()
        def block0():
            self._or_()
            self._logical_term_()
        self._closure(block0)

    @rule_def
    def _logical_term_(self):
        self._logical_factor_()
        def block0():
            self._and_()
            self._logical_factor_()
        self._closure(block0)

    @rule_def
    def _logical_factor_(self):
        with self._optional():
            self._not_()
        self._relation_()

    @rule_def
    def _relation_(self):
        self._arithmetic_expression_()
        with self._optional():
            self._rel_op_()
            self._arithmetic_expression_()

    @rule_def
    def _rel_op_(self):
        with self._choice():
            with self._option():
                self._token('<')
            with self._option():
                self._token('<=')
            with self._option():
                self._token('>')
            with self._option():
                self._token('>=')
            with self._option():
                self._token('==')
            with self._option():
                self._token('<>')
            self._error('expecting one of: > >= <> <= < ==')

    @rule_def
    def _arithmetic_expression_(self):
        with self._optional():
            self._add_op_()
        self._term_()
        def block0():
            self._add_op_()
            self._term_()
        self._closure(block0)

    @rule_def
    def _add_op_(self):
        with self._choice():
            with self._option():
                self._token('+')
            with self._option():
                self._token('-')
            with self._option():
                self._token('.+')
            with self._option():
                self._token('.-')
            self._error('expecting one of: + .- .+ -')

    @rule_def
    def _term_(self):
        self._factor_()
        def block0():
            self._mul_op_()
            self._factor_()
        self._closure(block0)

    @rule_def
    def _mul_op_(self):
        with self._choice():
            with self._option():
                self._token('*')
            with self._option():
                self._token('/')
            with self._option():
                self._token('.*')
            with self._option():
                self._token('./')
            self._error('expecting one of: ./ .* * /')

    @rule_def
    def _factor_(self):
        self._primary_()
        with self._optional():
            with self._group():
                with self._choice():
                    with self._option():
                        self._token('^')
                    with self._option():
                        self._token('.^')
                    self._error('expecting one of: ^ .^')
            self._primary_()

    @rule_def
    def _primary_(self):
        with self._choice():
            with self._option():
                self._UNSIGNED_NUMBER_()
            with self._option():
                self._STRING_()
            with self._option():
                self._false_()
            with self._option():
                self._true_()
            with self._option():
                with self._group():
                    with self._choice():
                        with self._option():
                            self._name_()
                        with self._option():
                            self._der_()
                        with self._option():
                            self._initial_()
                        self._error('no available options')
                self._function_call_args_()
            with self._option():
                self._component_reference_()
            with self._option():
                self._token('(')
                self._output_expression_list_()
                self._token(')')
            with self._option():
                self._token('[')
                self._expression_list_()
                def block1():
                    self._token(';')
                    self._expression_list_()
                self._closure(block1)
                self._token(']')
            with self._option():
                self._token('{')
                self._function_arguments_()
                self._token('}')
            with self._option():
                self._end_()
            self._error('no available options')

    @rule_def
    def _name_(self):
        self._IDENT_()

    @rule_def
    def _component_reference_(self):
        with self._optional():
            self._token('.')
        self._IDENT_()
        with self._optional():
            self._array_subscripts_()
        def block0():
            self._token('.')
            self._IDENT_()
            with self._optional():
                self._array_subscripts_()
        self._closure(block0)

    @rule_def
    def _function_call_args_(self):
        self._token('(')
        with self._optional():
            self._function_arguments_()
        self._token(')')

    @rule_def
    def _function_arguments_(self):
        with self._choice():
            with self._option():
                self._function_argument_()
                with self._optional():
                    with self._choice():
                        with self._option():
                            self._token(',')
                            self._function_arguments_()
                        with self._option():
                            self._for_()
                            self._for_indices_()
                        self._error('no available options')
            with self._option():
                self._named_arguments_()
            self._error('no available options')

    @rule_def
    def _named_arguments_(self):
        self._named_argument_()
        with self._optional():
            self._token(',')
            self._named_arguments_()

    @rule_def
    def _named_argument_(self):
        self._IDENT_()
        self._token('=')
        self._function_argument_()

    @rule_def
    def _function_argument_(self):
        with self._choice():
            with self._option():
                self._function_()
                self._name_()
                self._token('(')
                with self._optional():
                    self._named_arguments_()
                self._token(')')
            with self._option():
                self._expression_()
            self._error('no available options')

    @rule_def
    def _output_expression_list_(self):
        with self._optional():
            self._expression_()
        def block0():
            self._token(',')
            with self._optional():
                self._expression_()
        self._closure(block0)

    @rule_def
    def _expression_list_(self):
        self._expression_()
        def block0():
            self._token(',')
            self._expression_()
        self._closure(block0)

    @rule_def
    def _array_subscripts_(self):
        self._token('[')
        self._subscript_()
        def block0():
            self._token(',')
            self._subscript_()
        self._closure(block0)
        self._token(']')

    @rule_def
    def _subscript_(self):
        with self._choice():
            with self._option():
                self._token(':')
            with self._option():
                self._expression_()
            self._error('expecting one of: :')

    @rule_def
    def _comment_(self):
        self._string_comment_()
        with self._optional():
            self._annotation_()

    @rule_def
    def _string_comment_(self):
        with self._optional():
            self._STRING_()
            def block0():
                self._token('+')
                self._STRING_()
            self._closure(block0)

    @rule_def
    def _annotation_(self):
        with self._choice():
            with self._option():
                self._annotation_()
                self._class_modification_()
            with self._option():
                self._token('annotation')
            self._error('expecting one of: annotation')

    @rule_def
    def _algorithm_(self):
        self._token('algorithm')

    @rule_def
    def _and_(self):
        self._token('and')

    @rule_def
    def _assert_(self):
        self._token('assert')

    @rule_def
    def _block_(self):
        self._token('block')

    @rule_def
    def _break_(self):
        self._token('break')

    @rule_def
    def _class_(self):
        self._token('class')

    @rule_def
    def _connect_(self):
        self._token('connect')

    @rule_def
    def _connector_(self):
        self._token('connector')

    @rule_def
    def _constant_(self):
        self._token('constant')

    @rule_def
    def _constrainedby_(self):
        self._token('constrainedby')

    @rule_def
    def _der_(self):
        self._token('der')

    @rule_def
    def _discrete_(self):
        self._token('discrete')

    @rule_def
    def _each_(self):
        self._token('each')

    @rule_def
    def _else_(self):
        self._token('else')

    @rule_def
    def _elseif_(self):
        self._token('elseif')

    @rule_def
    def _elsewhen_(self):
        self._token('elsewhen')

    @rule_def
    def _encapsulated_(self):
        self._token('encapsulated')

    @rule_def
    def _end_(self):
        self._token('end')

    @rule_def
    def _enumeration_(self):
        self._token('enumeration')

    @rule_def
    def _expandable_(self):
        self._token('expandable')

    @rule_def
    def _extends_(self):
        self._token('extends')

    @rule_def
    def _external_(self):
        self._token('external')

    @rule_def
    def _false_(self):
        self._token('false')

    @rule_def
    def _final_(self):
        self._token('final')

    @rule_def
    def _flow_(self):
        self._token('flow')

    @rule_def
    def _for_(self):
        self._token('for')

    @rule_def
    def _function_(self):
        self._token('function')

    @rule_def
    def _if_(self):
        self._token('if')

    @rule_def
    def _import_(self):
        self._token('import')

    @rule_def
    def _impure_(self):
        self._token('impure')

    @rule_def
    def _in_(self):
        self._token('in')

    @rule_def
    def _initial_(self):
        self._token('initial')

    @rule_def
    def _inner_(self):
        self._token('inner')

    @rule_def
    def _input_(self):
        self._token('input')

    @rule_def
    def _loop_(self):
        self._token('loop')

    @rule_def
    def _model_(self):
        self._token('model')

    @rule_def
    def _not_(self):
        self._token('not')

    @rule_def
    def _operator_(self):
        self._token('operator')

    @rule_def
    def _or_(self):
        self._token('or')

    @rule_def
    def _outer_(self):
        self._token('outer')

    @rule_def
    def _output_(self):
        self._token('output')

    @rule_def
    def _package_(self):
        self._token('package')

    @rule_def
    def _parameter_(self):
        self._token('parameter')

    @rule_def
    def _partial_(self):
        self._token('partial')

    @rule_def
    def _protected_(self):
        self._token('protected')

    @rule_def
    def _public_(self):
        self._token('public')

    @rule_def
    def _pure_(self):
        self._token('pure')

    @rule_def
    def _record_(self):
        self._token('record')

    @rule_def
    def _redeclare_(self):
        self._token('redeclare')

    @rule_def
    def _replaceable_(self):
        self._token('replaceable')

    @rule_def
    def _return_(self):
        self._token('return')

    @rule_def
    def _stream_(self):
        self._token('stream')

    @rule_def
    def _then_(self):
        self._token('then')

    @rule_def
    def _true_(self):
        self._token('true')

    @rule_def
    def _type_(self):
        self._token('type')

    @rule_def
    def _when_(self):
        self._token('when')

    @rule_def
    def _while_(self):
        self._token('while')

    @rule_def
    def _within_(self):
        self._token('within')

    @rule_def
    def _re_IDENT_(self):
        self._pattern(r'[_a-zA-Z][_a-zA-Z0-9]*')

    @rule_def
    def _re_STRING_(self):
        self._pattern(r'"[^"]+"')

    @rule_def
    def _re_UNSIGNED_NUMBER_(self):
        self._pattern(r'[0-9]+([\.] [0-9]+)?[[eE][\+\-]?[0-9]+')

    @rule_def
    def _IDENT_(self):
        self._re_IDENT_()

    @rule_def
    def _STRING_(self):
        self._re_STRING_()

    @rule_def
    def _UNSIGNED_NUMBER_(self):
        self._re_UNSIGNED_NUMBER_()


class ModelicaSemanticParser(CheckSemanticsMixin, ModelicaParser):
    pass


class ModelicaSemantics(object):
    def stored_definition(self, ast):
        return ast

    def class_definition(self, ast):
        return ast

    def class_prefixes(self, ast):
        return ast

    def class_specifier(self, ast):
        return ast

    def base_prefix(self, ast):
        return ast

    def enum_list(self, ast):
        return ast

    def enumeration_literal(self, ast):
        return ast

    def composition(self, ast):
        return ast

    def language_specification(self, ast):
        return ast

    def external_function_call(self, ast):
        return ast

    def element_list(self, ast):
        return ast

    def element(self, ast):
        return ast

    def import_clause(self, ast):
        return ast

    def import_list(self, ast):
        return ast

    def extends_clause(self, ast):
        return ast

    def constraining_clause(self, ast):
        return ast

    def component_clause(self, ast):
        return ast

    def type_prefix(self, ast):
        return ast

    def type_specifier(self, ast):
        return ast

    def component_list(self, ast):
        return ast

    def component_declaration(self, ast):
        return ast

    def condition_attribute(self, ast):
        return ast

    def declaration(self, ast):
        return ast

    def modification(self, ast):
        return ast

    def class_modification(self, ast):
        return ast

    def argument_list(self, ast):
        return ast

    def argument(self, ast):
        return ast

    def element_modification_or_replaceable(self, ast):
        return ast

    def element_modification(self, ast):
        return ast

    def element_redeclaration(self, ast):
        return ast

    def element_replaceable(self, ast):
        return ast

    def component_clause1(self, ast):
        return ast

    def component_declaration1(self, ast):
        return ast

    def short_class_definition(self, ast):
        return ast

    def equation_section(self, ast):
        return ast

    def algorithm_section(self, ast):
        return ast

    def equation(self, ast):
        return ast

    def statement(self, ast):
        return ast

    def if_equation(self, ast):
        return ast

    def if_statement(self, ast):
        return ast

    def for_equation(self, ast):
        return ast

    def for_statement(self, ast):
        return ast

    def for_indices(self, ast):
        return ast

    def for_index(self, ast):
        return ast

    def while_statement(self, ast):
        return ast

    def when_equation(self, ast):
        return ast

    def when_statement(self, ast):
        return ast

    def connect_clause(self, ast):
        return ast

    def expression(self, ast):
        return ast

    def simple_expression(self, ast):
        return ast

    def logical_expression(self, ast):
        return ast

    def logical_term(self, ast):
        return ast

    def logical_factor(self, ast):
        return ast

    def relation(self, ast):
        return ast

    def rel_op(self, ast):
        return ast

    def arithmetic_expression(self, ast):
        return ast

    def add_op(self, ast):
        return ast

    def term(self, ast):
        return ast

    def mul_op(self, ast):
        return ast

    def factor(self, ast):
        return ast

    def primary(self, ast):
        return ast

    def name(self, ast):
        return ast

    def component_reference(self, ast):
        return ast

    def function_call_args(self, ast):
        return ast

    def function_arguments(self, ast):
        return ast

    def named_arguments(self, ast):
        return ast

    def named_argument(self, ast):
        return ast

    def function_argument(self, ast):
        return ast

    def output_expression_list(self, ast):
        return ast

    def expression_list(self, ast):
        return ast

    def array_subscripts(self, ast):
        return ast

    def subscript(self, ast):
        return ast

    def comment(self, ast):
        return ast

    def string_comment(self, ast):
        return ast

    def annotation(self, ast):
        return ast

    def algorithm(self, ast):
        return ast

    def and_(self, ast):
        return ast

    def assert_(self, ast):
        return ast

    def block(self, ast):
        return ast

    def break_(self, ast):
        return ast

    def class_(self, ast):
        return ast

    def connect(self, ast):
        return ast

    def connector(self, ast):
        return ast

    def constant(self, ast):
        return ast

    def constrainedby(self, ast):
        return ast

    def der(self, ast):
        return ast

    def discrete(self, ast):
        return ast

    def each(self, ast):
        return ast

    def else_(self, ast):
        return ast

    def elseif(self, ast):
        return ast

    def elsewhen(self, ast):
        return ast

    def encapsulated(self, ast):
        return ast

    def end(self, ast):
        return ast

    def enumeration(self, ast):
        return ast

    def expandable(self, ast):
        return ast

    def extends(self, ast):
        return ast

    def external(self, ast):
        return ast

    def false(self, ast):
        return ast

    def final(self, ast):
        return ast

    def flow(self, ast):
        return ast

    def for_(self, ast):
        return ast

    def function(self, ast):
        return ast

    def if_(self, ast):
        return ast

    def import_(self, ast):
        return ast

    def impure(self, ast):
        return ast

    def in_(self, ast):
        return ast

    def initial(self, ast):
        return ast

    def inner(self, ast):
        return ast

    def input(self, ast):
        return ast

    def loop(self, ast):
        return ast

    def model(self, ast):
        return ast

    def not_(self, ast):
        return ast

    def operator(self, ast):
        return ast

    def or_(self, ast):
        return ast

    def outer(self, ast):
        return ast

    def output(self, ast):
        return ast

    def package(self, ast):
        return ast

    def parameter(self, ast):
        return ast

    def partial(self, ast):
        return ast

    def protected(self, ast):
        return ast

    def public(self, ast):
        return ast

    def pure(self, ast):
        return ast

    def record(self, ast):
        return ast

    def redeclare(self, ast):
        return ast

    def replaceable(self, ast):
        return ast

    def return_(self, ast):
        return ast

    def stream(self, ast):
        return ast

    def then(self, ast):
        return ast

    def true(self, ast):
        return ast

    def type(self, ast):
        return ast

    def when(self, ast):
        return ast

    def while_(self, ast):
        return ast

    def within(self, ast):
        return ast

    def re_IDENT(self, ast):
        return ast

    def re_STRING(self, ast):
        return ast

    def re_UNSIGNED_NUMBER(self, ast):
        return ast

    def IDENT(self, ast):
        return ast

    def STRING(self, ast):
        return ast

    def UNSIGNED_NUMBER(self, ast):
        return ast


def main(filename, startrule, trace=False, whitespace=None):
    import json
    with open(filename) as f:
        text = f.read()
    parser = ModelicaParser(parseinfo=False)
    ast = parser.parse(
        text,
        startrule,
        filename=filename,
        trace=trace,
        whitespace=whitespace)
    print('AST:')
    print(ast)
    print()
    print('JSON:')
    print(json.dumps(ast, indent=2))
    print()

if __name__ == '__main__':
    import argparse
    import string
    import sys

    class ListRules(argparse.Action):
        def __call__(self, parser, namespace, values, option_string):
            print('Rules:')
            for r in ModelicaParser.rule_list():
                print(r)
            print()
            sys.exit(0)

    parser = argparse.ArgumentParser(description="Simple parser for Modelica.")
    parser.add_argument('-l', '--list', action=ListRules, nargs=0,
                        help="list all rules and exit")
    parser.add_argument('-t', '--trace', action='store_true',
                        help="output trace information")
    parser.add_argument('-w', '--whitespace', type=str, default=string.whitespace,
                        help="whitespace specification")
    parser.add_argument('file', metavar="FILE", help="the input file to parse")
    parser.add_argument('startrule', metavar="STARTRULE",
                        help="the start rule for parsing")
    args = parser.parse_args()

    main(args.file, args.startrule, trace=args.trace, whitespace=args.whitespace)
