Source code for modparc.syntax.class_definition

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pylint: disable=no-name-in-module, missing-docstring
"""
class_definition
----------------------------------

Parser definition for funcparserlib. The parsers that need forward declaration
are defined as function annotated by the `Parser` decorator.

The definitions are specified in the Appendix B.2.2 of the Modelica
Specification 3.3.
"""


from funcparserlib.parser import many, maybe, Parser

from modparc.syntax import keyword, op, token_type
from modparc.syntax.component_clause import type_prefix, component_clause
from modparc.syntax.equations import equation_section, algorithm_section
from modparc.syntax.expressions import (name, comment, annotation,
                                        string_comment, component_reference,
                                        array_subscript, expression_list)
from modparc.syntax.extends import extends_clause, constraining_clause
from modparc.syntax.modification import class_modification
from modparc.syntax.syntax_elements import (LanguageSpecification, BasePrefix,
                                            ExternalFunctionCall,
                                            ClassDefinition, Element,
                                            ElementList, Composition,
                                            ClassSpecifier, ClassPrefixes,
                                            EnumerationLiteral, EnumList,
                                            ImportList, ImportClause)
# pylint: enable=no-name-in-module

language_specification = token_type('string') >> LanguageSpecification

base_prefix = type_prefix >> BasePrefix

external_function_call = (maybe(component_reference + op("=")) +
                          token_type('ident') + op("(") +
                          maybe(expression_list) + op(")")
                          >> ExternalFunctionCall)


@Parser
def class_definition(tokens, state):
    parser = maybe(keyword("encapsulated")) + class_prefixes + class_specifier
    return (parser >> ClassDefinition).run(tokens, state)


[docs]def km(key): return maybe(keyword(key))
@Parser def element(tokens, state): kw = keyword parser = (import_clause | extends_clause | km('redeclare') + km('final') + km('inner') + km('outer') + ((class_definition | component_clause) | kw('replaceable') + (class_definition | component_clause) + maybe(constraining_clause + comment))) return (parser >> Element).run(tokens, state) element_list = maybe(many(element + op(';'))) >> ElementList composition = (element_list + maybe(many(keyword("public") + element_list | keyword("protected") + element_list | equation_section | algorithm_section)) + maybe(keyword("external") + maybe(language_specification) + maybe(external_function_call) + maybe(annotation) + op(";")) + maybe(annotation + op(";")) >> Composition) @Parser def class_specifier(tokens, state): normal = (token_type('ident') + string_comment + composition + keyword('end') + token_type('ident')) derived = (token_type('ident') + op("=") + base_prefix + name + maybe(array_subscript) + maybe(class_modification) + comment) enum_def = (token_type('ident') + op("=") + keyword('enumeration') + op("(") + (maybe(enum_list) | op(":")) + op(")") + comment) derivative = (token_type('ident') + op("=") + keyword('der') + op("(") + name + op(",") + token_type('ident') + maybe(many(op(",") + token_type('ident'))) + op(")") + comment) extended = (keyword('extends') + token_type('ident') + maybe(class_modification) + string_comment + composition + keyword("end") + token_type('ident')) parser = (normal | derived | enum_def | derivative | extended) return (parser >> ClassSpecifier).run(tokens, state) @Parser def class_prefixes(tokens, state): kw = keyword function_prefix = (maybe(kw("pure") | kw("impure")) + km("operator") + kw("function")) parser = (km("partial") + ((kw("class") | kw("model") | km("operator") + kw("record") | kw("block") | (km("expandable") + kw("connector")) | kw("type") | kw("package") | function_prefix | kw("operator")))) return (parser >> ClassPrefixes).run(tokens, state) enumeration_literal = token_type("ident") + comment >> EnumerationLiteral enum_list = enumeration_literal + maybe(many(op(",") + enumeration_literal)) >> EnumList import_list = (token_type("ident") + maybe(many(op(",") + token_type("ident"))) >> ImportList) import_clause = (keyword('import') + (token_type("ident") + op('=') + name | name + maybe(op(".*") | op(".") + op("{") + import_list + op("}"))) + comment) >> ImportClause