summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>2016-08-02 12:40:57 +0200
committerJuergen Ryannel <juergen.bocklage-ryannel@pelagicore.com>2016-11-30 10:01:19 +0100
commitada58821a68c61d9bc905ce793dd4d0f6b497645 (patch)
tree4f9dede65368fcb04155fc8298f3a2381b0705b9
parent6a3dd2248f24670ad70a28a70e848e33eac651c5 (diff)
downloadqtivi-qface-ada58821a68c61d9bc905ce793dd4d0f6b497645.tar.gz
initial commit
-rw-r--r--.gitignore3
-rw-r--r--README.md12
-rw-r--r--T.g496
-rwxr-xr-xcli.py87
-rwxr-xr-xcpp.py30
-rwxr-xr-xcsv.py10
-rw-r--r--examples/climate.qif107
-rw-r--r--examples/tuner.qif41
-rw-r--r--qif/__init__.py0
-rw-r--r--qif/generator.py108
-rw-r--r--qif/idl/__init__.py0
-rw-r--r--qif/idl/domain.py271
-rw-r--r--qif/idl/listener.py145
-rw-r--r--qif/idl/parser/T.tokens47
-rw-r--r--qif/idl/parser/TLexer.py162
-rw-r--r--qif/idl/parser/TLexer.tokens47
-rw-r--r--qif/idl/parser/TListener.py181
-rw-r--r--qif/idl/parser/TParser.py1475
-rw-r--r--qif/idl/parser/TVisitor.py108
-rw-r--r--qif/idl/parser/__init__.py0
-rw-r--r--templates/packages.csv11
-rw-r--r--templates/service.tpl.cpp44
-rw-r--r--templates/service.tpl.h29
-rw-r--r--templates/services.pro11
-rw-r--r--tests/test_climate.py29
-rw-r--r--tests/test_generator.py41
-rw-r--r--tests/test_parser.py81
27 files changed, 3172 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d382ab6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.cache
+__pycache__
+out
diff --git a/README.md b/README.md
index eb5a3d3..75a55a4 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,11 @@
-# qface
+# QML Interface Builder
-## Copyright and license
+Infrastructure to build a QML/Qt CPP interface based on an interface definition language and templates
-Copyright (C) 2016 Pelagicore AG
+# Dependencies
-The source code in this repository is subject to the terms of the GPLv3 licence, please see included "LICENSE" file for details.
+- Python3
+- ANTLR4
+- Jinja Templates
+
+# Running
diff --git a/T.g4 b/T.g4
new file mode 100644
index 0000000..80debd1
--- /dev/null
+++ b/T.g4
@@ -0,0 +1,96 @@
+grammar T;
+
+documentSymbol
+ : headerSymbol definitionSymbol*
+ ;
+
+headerSymbol
+ : packageSymbol importSymbol*
+ ;
+
+importSymbol
+ : 'import' name=IDENTIFIER ';'
+ ;
+
+packageSymbol
+ : comment=DOCCOMMENT? 'package' name=IDENTIFIER ';'
+ ;
+
+definitionSymbol
+ : serviceSymbol
+ | structSymbol
+ | enumSymbol
+ ;
+
+serviceSymbol
+ : comment=DOCCOMMENT? 'service' name=IDENTIFIER '{' memberSymbol* '}'
+ ;
+
+memberSymbol
+ : operationSymbol
+ | attributeSymbol
+ ;
+
+operationSymbol
+ : comment=DOCCOMMENT? isEvent='event'? (typeSymbol | 'void') name=IDENTIFIER '(' parameterSymbol* ')' ';'
+ ;
+
+attributeSymbol
+ : comment=DOCCOMMENT? isReadOnly='readonly'? typeSymbol name=IDENTIFIER ';'
+ ;
+
+parameterSymbol
+ : typeSymbol name=IDENTIFIER ','?
+ ;
+
+typeSymbol
+ : primitiveTypeSymbol
+ | complexTypeSymbol
+ ;
+
+complexTypeSymbol
+ : name=IDENTIFIER
+ ;
+
+primitiveTypeSymbol
+ : name='bool'
+ | name='int'
+ | name='real'
+ | name='string'
+ ;
+
+structSymbol
+ : comment=DOCCOMMENT? 'struct' name=IDENTIFIER '{' structMemberSymbol* '}'
+ ;
+
+structMemberSymbol
+ : comment=DOCCOMMENT? typeSymbol name=IDENTIFIER ';'?
+ ;
+
+enumSymbol
+ : comment=DOCCOMMENT? enumType name=IDENTIFIER '{' enumMemberSymbol* '}'
+ ;
+
+enumType
+ : isEnum = 'enum'
+ | isFlags = 'flags'
+ ;
+
+enumMemberSymbol
+ : comment=DOCCOMMENT? name=IDENTIFIER '=' intSymbol ','?
+ ;
+
+
+intSymbol
+ : value=INTCONSTANT
+ | value=HEXCONSTANT
+ ;
+
+
+INTCONSTANT : ('+' | '-')? '0'..'9'+;
+HEXCONSTANT : '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+;
+IDENTIFIER : [a-zA-Z0-9_][a-zA-Z0-9_\.]*;
+DOCCOMMENT : '/*!' .*? '*/';
+WHITESPACE : [ \t\r\n]+ -> skip;
+COMMENT : '//' ~[\r\n]* -> skip;
+MULTICOMM : '/*' .*? '*/' -> skip;
diff --git a/cli.py b/cli.py
new file mode 100755
index 0000000..0ca3d4a
--- /dev/null
+++ b/cli.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+import click
+from subprocess import call
+from watchdog.events import FileSystemEventHandler
+from watchdog.observers import Observer
+from pathlib import Path
+import time
+
+
+def sh(cmd, all=False):
+ click.echo('$ {0}'.format(cmd))
+ return call(cmd, shell=True)
+
+
+@click.group()
+def cli():
+ pass
+
+
+@cli.command()
+def antlr():
+ sh('antlr4 -Dlanguage=Python3 -Werror -package qif.idl.parser -o qif/idl/parser -listener -visitor T.g4')
+
+
+@cli.command()
+def test():
+ sh('python3 -m pytest -v -s -l --pdb')
+
+
+class RunTestChangeHandler(FileSystemEventHandler):
+ def __init__(self, clickContext):
+ super(RunTestChangeHandler).__init__()
+ self.clickContext = clickContext
+
+ def on_any_event(self, event):
+ if event.is_directory:
+ return
+ if Path(event.src_path).suffix == '.py':
+ sh('python3 -m pytest -v -s -l --pdb')
+
+
+@cli.command()
+@click.pass_context
+def test_monitor(ctx):
+ while True:
+ event_handler = RunTestChangeHandler(ctx)
+ observer = Observer()
+ observer.schedule(event_handler, '.', recursive=True)
+ observer.start()
+ try:
+ while True:
+ time.sleep(1)
+ except KeyboardInterrupt:
+ observer.stop()
+ observer.join()
+
+
+class RunScriptChangeHandler(FileSystemEventHandler):
+ def __init__(self, script):
+ super(RunTestChangeHandler).__init__()
+ self.script = script
+
+ def on_modified(self, event):
+ if event.src_path.endswith('.cache'):
+ return
+ print(event)
+ sh(self.script)
+
+
+@cli.command()
+@click.option('--script')
+def generator_monitor(script):
+ print('run script: ' + script)
+ event_handler = RunScriptChangeHandler(script)
+ observer = Observer()
+ observer.schedule(event_handler, './templates', recursive=True)
+ observer.schedule(event_handler, str(Path(script).parent), recursive=False)
+ observer.start()
+ try:
+ while True:
+ time.sleep(5)
+ except KeyboardInterrupt:
+ observer.stop()
+ observer.join()
+
+if __name__ == '__main__':
+ cli()
diff --git a/cpp.py b/cpp.py
new file mode 100755
index 0000000..6281d36
--- /dev/null
+++ b/cpp.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+from qif.generator import FileSystem, Generator
+
+system = FileSystem.parse_dir('./examples')
+
+
+def paramterType(symbol):
+ if symbol.type.is_void or symbol.type.is_primitive:
+ return '{0} {1}'.format(symbol.type, symbol)
+ else:
+ return 'const {0} &{1}'.format(symbol.type, symbol)
+
+
+def returnType(symbol):
+ if symbol.type.is_void or symbol.type.is_primitive:
+ return symbol.type
+ else:
+ return symbol.type
+
+generator = Generator()
+generator.register_filter('returnType', returnType)
+generator.register_filter('parameterType', paramterType)
+
+for package in system.packages:
+ for service in package.services:
+ ctx = {'service': service, 'package': package}
+ generator.write('out/{{service|lower}}.h', 'service.tpl.h', ctx)
+ generator.write('out/{{service|lower}}.cpp', 'service.tpl.cpp', ctx)
+ ctx = {'package': package}
+ generator.write('out/{{package}}.pro', 'services.pro', ctx)
diff --git a/csv.py b/csv.py
new file mode 100755
index 0000000..c0d450b
--- /dev/null
+++ b/csv.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+from qif.generator import FileSystem, Generator
+
+system = FileSystem.parse_dir('./examples')
+
+
+generator = Generator()
+
+ctx = {'system': system}
+generator.write('out/packages.csv', 'packages.csv', ctx)
diff --git a/examples/climate.qif b/examples/climate.qif
new file mode 100644
index 0000000..b393081
--- /dev/null
+++ b/examples/climate.qif
@@ -0,0 +1,107 @@
+package vehicle.climate;
+
+/*!
+ * The ClimateControl provides a QML interface to the climate control
+ * of the vehicle.
+ */
+service ClimateControl {
+ /*!
+ * Value is true if the air conditioning is enabled.
+ */
+ bool airConditioning;
+ /*!
+ * value holds the airflow directions
+ */
+ AirflowDirections airflowDirections;
+ /*!
+ * value holds the intensity level of the fan when the climateMode
+ * is set to AutoClimate, where the level can be between
+ * minimumValue(least intensity) to maximumValue(most intensity).
+ */
+ int automaticClimateFanIntensityLevel;
+ /*!
+ * value holds the climate mode
+ */
+ ClimateMode climateMode;
+ /*!
+ * value is true if defrost is enabled. Usually that means that the fans
+ * are on the highest level to remove ice from the windshield.
+ */
+ bool defrost;
+ /*!
+ * value holds the fan speed level, where the level can be between
+ * minimumValue(off) to maximumValue (strongest).
+ */
+ int fanSpeedLevel;
+ /*!
+ * value is true if the heater is enabled.
+ */
+ bool heater;
+ /*!
+ * value holds the outside temperature of the zone expressed in
+ * centigrades, where the temperature can be between
+ * minimumValue(coolest) to maximumValue (warmest).
+ */
+ int outsideTemperature;
+ /*!
+ * value is true if the recirculation is currently running.
+ */
+ bool recirculation;
+ /*!
+ * value holds the recirculation mode
+ */
+ RecirculationMode recirculationMode;
+ /*!
+ * value holds the sensitivity level of the recirculation
+ * system when the recirculationMode is set to AutoRecirculation,
+ * where the level can be between minimumValue(least sensitive)
+ * to maximumValue(most sensitive).
+ */
+ int recirculationSensitivityLevel;
+ /*!
+ * value holds the seat cooler level, where the level can be
+ * between minimumValue(off) to maximumValue (coolest).
+ */
+ int seatCooler;
+ /*!
+ * value holds the seat heater level, where the level can be between
+ * minimumValue(off) to maximumValue (warmest).
+ */
+ int seatHeater;
+ /*!
+ * value holds the steering wheel heater level, where the level can
+ * be between minimumValue(off) to maximumValue (warmest).
+ */
+ int steeringWheelHeater;
+ /*!
+ * value holds the target temperature of the zone expressed
+ * in centigrades, where the temperature can be between
+ * minimumValue(coolest) to maximumValue (warmest).
+ */
+ int targetTemperature;
+ /*!
+ * value is true if the zone synchronization is enabled.
+ *
+ * Which zones and properties are synchronized is controlled
+ * by the backend implementing it.
+ */
+ bool zoneSynchronization;
+}
+
+flags AirflowDirections {
+ Windshield = 0x1,
+ Dashboard = 0x2,
+ Floor = 0x4
+}
+
+enum ClimateMode {
+ ClimateOff = 0x0,
+ ClimateOn = 0x1,
+ AutoClimate = 0x2
+}
+
+enum RecirculationMode {
+ RecirculationOff = 0x0,
+ RecirculationOn = 0x1,
+ AutoRecirculation = 0x2
+}
diff --git a/examples/tuner.qif b/examples/tuner.qif
new file mode 100644
index 0000000..888a420
--- /dev/null
+++ b/examples/tuner.qif
@@ -0,0 +1,41 @@
+package entertainment.tuner;
+
+/*! Service Tuner */
+service Tuner {
+ /*! attribute currentStation */
+ readonly Station currentStation;
+ /*! operation nextStation */
+ void nextStation();
+ /*! operation previousStation */
+ void previousStation();
+ /*! operation updateCurrentStation */
+ void updateCurrentStation(int stationId);
+}
+
+/*! enum State */
+enum State {
+ /*! value State.Null */
+ Null=0,
+ /*! value State.Loading */
+ Loading=1,
+ /*! value State.Ready */
+ Ready=2,
+ /*! value State.Error */
+ Error=3
+}
+
+/*! enum Waveband */
+enum Waveband {
+ /*! value Waveband.FM */
+ FM=0,
+ /*! value Waveband.AM */
+ AM=1
+}
+
+/*! struct Station */
+struct Station {
+ /*! member stationId */
+ int stationId;
+ /*! member name */
+ string name;
+}
diff --git a/qif/__init__.py b/qif/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/qif/__init__.py
diff --git a/qif/generator.py b/qif/generator.py
new file mode 100644
index 0000000..19b01c6
--- /dev/null
+++ b/qif/generator.py
@@ -0,0 +1,108 @@
+from jinja2 import Environment, FileSystemLoader, Template
+from pathlib import Path
+import shelve
+import logging
+
+from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker
+from antlr4.error import DiagnosticErrorListener
+
+from .idl.parser.TLexer import TLexer
+from .idl.parser.TParser import TParser
+from .idl.parser.TListener import TListener
+from .idl.domain import System
+from .idl.listener import DomainListener
+
+
+logger = logging.getLogger(__name__)
+
+
+def upper_first_filter(s):
+ s = str(s)
+ return s[0].upper() + s[1:]
+
+
+class Generator(object):
+ def __init__(self, folder: str ='templates'):
+ folder = Path(folder).resolve().as_posix()
+ self.env = Environment(loader=FileSystemLoader(folder), trim_blocks=True, lstrip_blocks=True)
+ self.register_filters()
+
+ def get_template(self, name: str):
+ return self.env.get_template(name)
+
+ def render(self, name: str, context: dict):
+ template = self.get_template(name)
+ return template.render(context)
+
+ def apply(self, template: Template, context: dict):
+ return Template(template).render(context)
+
+ def write(self, fileTemplate: str, template: str, context: dict):
+ path = Path(self.apply(fileTemplate, context))
+ self.mkdir(path.parent)
+ logger.info('write {0}'.format(path))
+ data = self.render(template, context)
+ path.open('w').write(data)
+
+ def mkdir(self, path: str):
+ path = Path(path)
+ try:
+ path.mkdir(parents=True)
+ except OSError:
+ pass
+
+ def register_filters(self):
+ self.env.filters['upperfirst'] = upper_first_filter
+
+ def register_filter(self, name, callback):
+ self.env.filters[name] = callback
+
+
+
+class FileSystem(object):
+ @staticmethod
+ def parse_document(path: str, system: System = None):
+ system = system or System()
+ listener = DomainListener(system)
+ FileSystem._parse_document(path, listener)
+ return system
+
+ @staticmethod
+ def _parse_document(path: str, listener: TListener):
+ logger.debug('parse document: {0}'.format(path))
+ data = FileStream(str(path), encoding='utf-8')
+ lexer = TLexer(data)
+ stream = CommonTokenStream(lexer)
+ parser = TParser(stream)
+ parser.addErrorListener(DiagnosticErrorListener.DiagnosticErrorListener())
+ tree = parser.documentSymbol()
+ walker = ParseTreeWalker()
+ walker.walk(listener, tree)
+
+ @staticmethod
+ def parse_dir(path, identifier: str = None, clear_cache=True):
+ path = Path(path)
+ logging.debug('parse_tree path={0}'.format(path))
+ if not identifier:
+ identifier = 'system'
+ system = System()
+ cache = shelve.open('qif.cache')
+ if identifier in cache and clear_cache:
+ del cache[identifier]
+ if identifier in cache:
+ # use the cached domain model
+ system = cache[identifier]
+ else:
+ # if domain model not cached generate it
+ documents = path.rglob('*.qif')
+ for document in documents:
+ listener = DomainListener(system)
+ FileSystem._parse_document(document, listener)
+ cache[identifier] = system
+ return system
+
+ @staticmethod
+ def find_files(path, glob='*.qif'):
+ path = Path(path)
+ logging.debug('find_files path={0} glob={1}'.format(path, glob))
+ return path.rglob(glob)
diff --git a/qif/idl/__init__.py b/qif/idl/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/qif/idl/__init__.py
diff --git a/qif/idl/domain.py b/qif/idl/domain.py
new file mode 100644
index 0000000..f101599
--- /dev/null
+++ b/qif/idl/domain.py
@@ -0,0 +1,271 @@
+from collections import OrderedDict, ChainMap
+import logging
+
+log = logging.getLogger(__name__)
+
+# System
+# +- Package
+# +- Import
+# +- Service
+# +- Attribute
+# +- Operation
+# +- Struct
+# +- Enum
+
+
+
+class System(object):
+ def __init__(self):
+ log.debug('System()')
+ self.packageMap = OrderedDict() # type: Dict[str, Package]
+
+ def __unicode__(self):
+ return 'system'
+
+ def __repr__(self):
+ return '<System>'
+
+ @property
+ def packages(self):
+ return self.packageMap.values()
+
+ def lookup_package(self, name: str):
+ return self.packageMap[name]
+
+ def lookup_service(self, name: str):
+ package_name, type_name = name.rsplit('.', 1)
+ package = self.packageMap[package_name]
+ return package.serviceMap[type_name]
+
+ def lookup_struct(self, name: str):
+ package_name, type_name = name.rsplit('.', 1)
+ package = self.packageMap[package_name]
+ return package.structMap[type_name]
+
+ def lookup_enum(self, name: str):
+ package_name, type_name = name.rsplit('.', 1)
+ package = self.packageMap[package_name]
+ return package.enumMap[type_name]
+
+ def lookup_definition(self, name: str):
+ parts = name.rsplit('.', 1)
+ if len(parts) == 2:
+ package_name = parts[0]
+ type_name = parts[1]
+ package = self.packageMap[package_name]
+ return package.lookup_definition(type_name)
+
+ @property
+ def system(self):
+ return self
+
+
+class Package(object):
+ def __init__(self, name: str, system: System):
+ log.debug('Package()')
+ self.name = name
+ self.system = system
+ self.system.packageMap[name] = self
+ self.serviceMap = OrderedDict() # type: Dict[str, Service]
+ self.structMap = OrderedDict() # type: Dict[str, Struct]
+ self.enumMap = OrderedDict() # type: Dict[str, Enum]
+ self.definitionMap = ChainMap(self.serviceMap, self.structMap, self.enumMap)
+ self.importMap = OrderedDict() # type: Dict[str, Package]
+
+ @property
+ def services(self):
+ return self.serviceMap.values()
+
+ @property
+ def structs(self):
+ return self.structMap.values()
+
+ @property
+ def enums(self):
+ return self.enumMap.values()
+
+ @property
+ def imports(self):
+ return self.importMap.values()
+
+ def lookup_definition(self, name: str):
+ if name in self.definitionMap:
+ return self.definitionMap[name]
+
+ def lookup_package(self, name: str):
+ if name in self.system.packageMap:
+ return self.system.packageMap[name]
+
+ def __unicode__(self):
+ return self.name
+
+ def __repr__(self):
+ return self.name
+
+
+class Symbol(object):
+ def __init__(self, name: str, package: Package):
+ self.name = name
+ self.package = package
+ self.comment = None
+
+ @property
+ def system(self):
+ return self.package.system
+
+ def __unicode__(self):
+ return self.name
+
+ def __repr__(self):
+ return self.name
+
+ @property
+ def qualifiedName(self):
+ return '{0}.{1}'.format(self.package.name, self.name)
+
+
+class TypedSymbol(Symbol):
+ def __init__(self, name: str, package: Package):
+ super().__init__(name, package)
+ self.type = TypeSymbol("", self)
+
+
+class TypeSymbol(Symbol):
+ def __init__(self, name: str, parent: Symbol):
+ super().__init__(name, parent.package)
+ log.debug('TypeSymbol()')
+ self.parent = parent
+ self.is_void = False # type:bool
+ self.is_primitive = False # type:bool
+ self.is_complex = False # type:bool
+
+ @property
+ def is_bool(self):
+ return self.is_primitive and self.name == 'bool'
+
+ @property
+ def is_int(self):
+ return self.is_primitive and self.name == 'int'
+
+ @property
+ def is_real(self):
+ return self.is_primitive and self.name == 'real'
+
+ @property
+ def is_string(self):
+ return self.is_primitive and self.name == 'string'
+
+ @property
+ def definition(self):
+ if not self.is_complex:
+ return
+ result = self.package.lookup_definition(self.name)
+ if not result:
+ result = self.system.lookup_definition(self.name)
+ return result
+
+ @property
+ def is_enum(self):
+ return self.is_complex and isinstance(self.definition, Enum)
+
+ @property
+ def is_struct(self):
+ return self.is_complex and isinstance(self.definition, Struct)
+
+
+
+class Service(Symbol):
+ def __init__(self, name: str, package: Package):
+ super().__init__(name, package)
+ log.debug('Service()')
+ self.package.serviceMap[name] = self
+ self.attributeMap = OrderedDict() # type: Dict[str, Attribute]
+ self.operationMap = OrderedDict() # type: Dict[str, Operation]
+ self.eventMap = OrderedDict() # type: Dict[str, Operation]
+
+ @property
+ def attributes(self):
+ return self.attributeMap.values()
+
+ @property
+ def operations(self):
+ return self.operationMap.values()
+
+ @property
+ def events(self):
+ return self.eventMap.values()
+
+
+class Struct(Symbol):
+ def __init__(self, name: str, package: Package):
+ super().__init__(name, package)
+ log.debug('Struct()')
+ self.package.structMap[name] = self
+ self.memberMap = OrderedDict() # type: Dict[str, Member]
+
+ @property
+ def members(self):
+ return self.memberMap.values()
+
+
+class Member(TypedSymbol):
+ def __init__(self, name: str, struct: Struct):
+ super().__init__(name, struct.package)
+ log.debug('Member()')
+ self.struct = struct # type:Struct
+ self.struct.memberMap[name] = self
+
+
+class Operation(TypedSymbol):
+ def __init__(self, name: str, service: Service, is_event=False):
+ super().__init__(name, service.package)
+ log.debug('Operation()')
+ self.service = service
+ self.is_event = is_event
+ if is_event:
+ self.service.eventMap[name] = self
+ else:
+ self.service.operationMap[name] = self
+ self.parameterMap = OrderedDict() # type: Dict[Parameter]
+
+ @property
+ def parameters(self):
+ return self.parameterMap.values()
+
+
+class Attribute(TypedSymbol):
+ def __init__(self, name: str, service: Service):
+ super().__init__(name, service.package)
+ log.debug('Attribute()')
+ self.service = service
+ self.service.attributeMap[name] = self
+ self.is_readonly = False
+
+
+class Enum(Symbol):
+ def __init__(self, name: str, package: Package):
+ super().__init__(name, package)
+ log.debug('Enum()')
+ self.package.enumMap[name] = self
+ self.memberMap = OrderedDict() # type: Dict[EnumMember]
+
+ @property
+ def members(self):
+ return self.memberMap
+
+
+class EnumMember(Symbol):
+ def __init__(self, name: str, enum: Enum):
+ super().__init__(name, enum.package)
+ log.debug('EnumMember()')
+ self.enum = enum
+ self.enum.memberMap[name] = self
+ self.value = None
+
+
+class Parameter(TypedSymbol):
+ def __init__(self, name: str, operation: Operation):
+ super().__init__(name, operation.package)
+ log.debug('Parameter()')
+ self.operation = operation
+ self.operation.parameterMap[name] = self
diff --git a/qif/idl/listener.py b/qif/idl/listener.py
new file mode 100644
index 0000000..b9849d4
--- /dev/null
+++ b/qif/idl/listener.py
@@ -0,0 +1,145 @@
+import logging
+from .parser.TListener import TListener
+from .parser.TParser import TParser
+from .domain import *
+
+
+log = logging.getLogger(__name__)
+
+
+class DomainListener(TListener):
+ def __init__(self, system):
+ super(DomainListener, self).__init__()
+ self.system = system or System() # type:System
+ self.package = None # type:Package
+ self.service = None # type:Service
+ self.struct = None # type:Struct
+ self.enum = None # type:Enum
+ self.operation = None # type:Operation
+ self.parameter = None # type:Parameter
+ self.attribute = None # type:Attribute
+ self.member = None # type:Member
+
+ def parse_type(self, ctx, symbol: TypedSymbol):
+ if not ctx.typeSymbol():
+ # import pdb; pdb.set_trace()
+ symbol.type.is_void = True
+ symbol.type.name = 'void'
+ else:
+ if ctx.typeSymbol().primitiveTypeSymbol():
+ ctxSymbol = ctx.typeSymbol().primitiveTypeSymbol() # type:TParser.PrimitiveTypeSymbolContext
+ symbol.type.is_primitive = True
+ symbol.type.name = ctxSymbol.name.text
+ if ctx.typeSymbol().complexTypeSymbol():
+ ctxSymbol = ctx.typeSymbol().complexTypeSymbol() # type:TParser.ComplexTypeSymbolContext
+ symbol.type.is_complex = True
+ symbol.type.name = ctxSymbol.name.text
+
+ def parse_comment(self, ctx, symbol):
+ if ctx.comment:
+ comment = ctx.comment.text
+ symbol.comment = comment
+
+
+ def enterEveryRule(self, ctx):
+ log.debug('enter ' + ctx.__class__.__name__)
+
+ def exitEveryRule(self, ctx):
+ log.debug('exit ' + ctx.__class__.__name__)
+
+ def enterPackageSymbol(self, ctx: TParser.PackageSymbolContext):
+ assert self.system
+ name = ctx.name.text
+ self.package = Package(name, self.system)
+
+ def exitPackageSymbol(self, ctx: TParser.PackageSymbolContext):
+ pass
+
+ def enterServiceSymbol(self, ctx: TParser.ServiceSymbolContext):
+ assert self.package
+ name = ctx.name.text
+ self.service = Service(name, self.package)
+ self.parse_comment(ctx, self.service)
+
+ def exitServiceSymbol(self, ctx: TParser.ServiceSymbolContext):
+ self.service = None
+
+ def enterStructSymbol(self, ctx: TParser.StructSymbolContext):
+ assert self.package
+ name = ctx.name.text
+ self.struct = Struct(name, self.package)
+ self.parse_comment(ctx, self.struct)
+
+ def exitStructSymbol(self, ctx: TParser.StructSymbolContext):
+ self.struct = None
+
+ def enterEnumSymbol(self, ctx: TParser.EnumSymbolContext):
+ assert self.package
+ name = ctx.name.text
+ self.enum = Enum(name, self.package)
+ self.parse_comment(ctx, self.enum)
+
+ def exitEnumSymbol(self, ctx: TParser.EnumSymbolContext):
+ self.enum = None
+
+ def enterOperationSymbol(self, ctx: TParser.OperationSymbolContext):
+ assert self.service
+ name = ctx.name.text
+ is_event = bool(ctx.isEvent)
+ self.operation = Operation(name, self.service, is_event)
+ self.parse_comment(ctx, self.operation)
+ self.parse_type(ctx, self.operation)
+
+ def exitOperationSymbol(self, ctx: TParser.OperationSymbolContext):
+ self.operation = None
+
+ def enterParameterSymbol(self, ctx: TParser.ParameterSymbolContext):
+ name = ctx.name.text
+ self.parameter = Parameter(name, self.operation)
+
+ def exitParameterSymbol(self, ctx: TParser.ParameterSymbolContext):
+ self.parse_type(ctx, self.parameter)
+
+ def enterAttributeSymbol(self, ctx: TParser.AttributeSymbolContext):
+ assert self.service
+ name = ctx.name.text
+ self.attribute = Attribute(name, self.service)
+ self.attribute.is_readonly = bool(ctx.isReadOnly)
+ self.parse_comment(ctx, self.attribute)
+ self.parse_type(ctx, self.attribute)
+
+ def exitAttributeSymbol(self, ctx: TParser.AttributeSymbolContext):
+ self.attribute = None
+
+ def enterStructMemberSymbol(self, ctx: TParser.StructMemberSymbolContext):
+ assert self.struct
+ name = ctx.name.text
+ self.member = Member(name, self.struct)
+
+ def exitStructMemberSymbol(self, ctx: TParser.StructMemberSymbolContext):
+ self.parse_type(ctx, self.member)
+ self.member = None
+
+ def enterEnumMemberSymbol(self, ctx: TParser.EnumMemberSymbolContext):
+ assert self.enum
+ name = ctx.name.text
+ self.member = EnumMember(name, self.enum)
+ self.member.value = int(ctx.intSymbol().value.text, 0)
+
+ def exitEnumMemberSymbol(self, ctx: TParser.EnumMemberSymbolContext):
+ self.member = None
+
+ def enterImportSymbol(self, ctx:TParser.ImportSymbolContext):
+ assert self.package
+ name = ctx.name.text
+ self.package.importMap[name] = None
+
+
+ def exitImportSymbol(self, ctx:TParser.ImportSymbolContext):
+ pass
+
+
+
+
+
+
diff --git a/qif/idl/parser/T.tokens b/qif/idl/parser/T.tokens
new file mode 100644
index 0000000..c9d702b
--- /dev/null
+++ b/qif/idl/parser/T.tokens
@@ -0,0 +1,47 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+T__13=14
+T__14=15
+T__15=16
+T__16=17
+T__17=18
+T__18=19
+T__19=20
+INTCONSTANT=21
+HEXCONSTANT=22
+IDENTIFIER=23
+DOCCOMMENT=24
+WHITESPACE=25
+COMMENT=26
+MULTICOMM=27
+'import'=1
+';'=2
+'package'=3
+'service'=4
+'{'=5
+'}'=6
+'event'=7
+'void'=8
+'('=9
+')'=10
+'readonly'=11
+','=12
+'bool'=13
+'int'=14
+'real'=15
+'string'=16
+'struct'=17
+'enum'=18
+'flags'=19
+'='=20
diff --git a/qif/idl/parser/TLexer.py b/qif/idl/parser/TLexer.py
new file mode 100644
index 0000000..8176d50
--- /dev/null
+++ b/qif/idl/parser/TLexer.py
@@ -0,0 +1,162 @@
+# Generated from T.g4 by ANTLR 4.5.2
+from antlr4 import *
+from io import StringIO
+
+
+def serializedATN():
+ with StringIO() as buf:
+ buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\35")
+ buf.write("\u00dd\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7")
+ buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r")
+ buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23")
+ buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30")
+ buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\3\2\3\2\3\2\3")
+ buf.write("\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4")
+ buf.write("\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3")
+ buf.write("\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\13\3")
+ buf.write("\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\16\3")
+ buf.write("\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\20\3\20\3\20")
+ buf.write("\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22")
+ buf.write("\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24")
+ buf.write("\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\26\5\26\u009b\n")
+ buf.write("\26\3\26\6\26\u009e\n\26\r\26\16\26\u009f\3\27\3\27\3")
+ buf.write("\27\3\27\6\27\u00a6\n\27\r\27\16\27\u00a7\3\30\3\30\7")
+ buf.write("\30\u00ac\n\30\f\30\16\30\u00af\13\30\3\31\3\31\3\31\3")
+ buf.write("\31\3\31\7\31\u00b6\n\31\f\31\16\31\u00b9\13\31\3\31\3")
+ buf.write("\31\3\31\3\32\6\32\u00bf\n\32\r\32\16\32\u00c0\3\32\3")
+ buf.write("\32\3\33\3\33\3\33\3\33\7\33\u00c9\n\33\f\33\16\33\u00cc")
+ buf.write("\13\33\3\33\3\33\3\34\3\34\3\34\3\34\7\34\u00d4\n\34\f")
+ buf.write("\34\16\34\u00d7\13\34\3\34\3\34\3\34\3\34\3\34\4\u00b7")
+ buf.write("\u00d5\2\35\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25")
+ buf.write("\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+")
+ buf.write("\27-\30/\31\61\32\63\33\65\34\67\35\3\2\b\4\2--//\5\2")
+ buf.write("\62;CHch\6\2\62;C\\aac|\b\2\60\60\62;C\\^^aac|\5\2\13")
+ buf.write("\f\17\17\"\"\4\2\f\f\17\17\u00e4\2\3\3\2\2\2\2\5\3\2\2")
+ buf.write("\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2")
+ buf.write("\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27")
+ buf.write("\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3")
+ buf.write("\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2")
+ buf.write(")\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2")
+ buf.write("\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\39\3\2\2\2\5")
+ buf.write("@\3\2\2\2\7B\3\2\2\2\tJ\3\2\2\2\13R\3\2\2\2\rT\3\2\2\2")
+ buf.write("\17V\3\2\2\2\21\\\3\2\2\2\23a\3\2\2\2\25c\3\2\2\2\27e")
+ buf.write("\3\2\2\2\31n\3\2\2\2\33p\3\2\2\2\35u\3\2\2\2\37y\3\2\2")
+ buf.write("\2!~\3\2\2\2#\u0085\3\2\2\2%\u008c\3\2\2\2\'\u0091\3\2")
+ buf.write("\2\2)\u0097\3\2\2\2+\u009a\3\2\2\2-\u00a1\3\2\2\2/\u00a9")
+ buf.write("\3\2\2\2\61\u00b0\3\2\2\2\63\u00be\3\2\2\2\65\u00c4\3")
+ buf.write("\2\2\2\67\u00cf\3\2\2\29:\7k\2\2:;\7o\2\2;<\7r\2\2<=\7")
+ buf.write("q\2\2=>\7t\2\2>?\7v\2\2?\4\3\2\2\2@A\7=\2\2A\6\3\2\2\2")
+ buf.write("BC\7r\2\2CD\7c\2\2DE\7e\2\2EF\7m\2\2FG\7c\2\2GH\7i\2\2")
+ buf.write("HI\7g\2\2I\b\3\2\2\2JK\7u\2\2KL\7g\2\2LM\7t\2\2MN\7x\2")
+ buf.write("\2NO\7k\2\2OP\7e\2\2PQ\7g\2\2Q\n\3\2\2\2RS\7}\2\2S\f\3")
+ buf.write("\2\2\2TU\7\177\2\2U\16\3\2\2\2VW\7g\2\2WX\7x\2\2XY\7g")
+ buf.write("\2\2YZ\7p\2\2Z[\7v\2\2[\20\3\2\2\2\\]\7x\2\2]^\7q\2\2")
+ buf.write("^_\7k\2\2_`\7f\2\2`\22\3\2\2\2ab\7*\2\2b\24\3\2\2\2cd")
+ buf.write("\7+\2\2d\26\3\2\2\2ef\7t\2\2fg\7g\2\2gh\7c\2\2hi\7f\2")
+ buf.write("\2ij\7q\2\2jk\7p\2\2kl\7n\2\2lm\7{\2\2m\30\3\2\2\2no\7")
+ buf.write(".\2\2o\32\3\2\2\2pq\7d\2\2qr\7q\2\2rs\7q\2\2st\7n\2\2")
+ buf.write("t\34\3\2\2\2uv\7k\2\2vw\7p\2\2wx\7v\2\2x\36\3\2\2\2yz")
+ buf.write("\7t\2\2z{\7g\2\2{|\7c\2\2|}\7n\2\2} \3\2\2\2~\177\7u\2")
+ buf.write("\2\177\u0080\7v\2\2\u0080\u0081\7t\2\2\u0081\u0082\7k")
+ buf.write("\2\2\u0082\u0083\7p\2\2\u0083\u0084\7i\2\2\u0084\"\3\2")
+ buf.write("\2\2\u0085\u0086\7u\2\2\u0086\u0087\7v\2\2\u0087\u0088")
+ buf.write("\7t\2\2\u0088\u0089\7w\2\2\u0089\u008a\7e\2\2\u008a\u008b")
+ buf.write("\7v\2\2\u008b$\3\2\2\2\u008c\u008d\7g\2\2\u008d\u008e")
+ buf.write("\7p\2\2\u008e\u008f\7w\2\2\u008f\u0090\7o\2\2\u0090&\3")
+ buf.write("\2\2\2\u0091\u0092\7h\2\2\u0092\u0093\7n\2\2\u0093\u0094")
+ buf.write("\7c\2\2\u0094\u0095\7i\2\2\u0095\u0096\7u\2\2\u0096(\3")
+ buf.write("\2\2\2\u0097\u0098\7?\2\2\u0098*\3\2\2\2\u0099\u009b\t")
+ buf.write("\2\2\2\u009a\u0099\3\2\2\2\u009a\u009b\3\2\2\2\u009b\u009d")
+ buf.write("\3\2\2\2\u009c\u009e\4\62;\2\u009d\u009c\3\2\2\2\u009e")
+ buf.write("\u009f\3\2\2\2\u009f\u009d\3\2\2\2\u009f\u00a0\3\2\2\2")
+ buf.write("\u00a0,\3\2\2\2\u00a1\u00a2\7\62\2\2\u00a2\u00a3\7z\2")
+ buf.write("\2\u00a3\u00a5\3\2\2\2\u00a4\u00a6\t\3\2\2\u00a5\u00a4")
+ buf.write("\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a7")
+ buf.write("\u00a8\3\2\2\2\u00a8.\3\2\2\2\u00a9\u00ad\t\4\2\2\u00aa")
+ buf.write("\u00ac\t\5\2\2\u00ab\u00aa\3\2\2\2\u00ac\u00af\3\2\2\2")
+ buf.write("\u00ad\u00ab\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\60\3\2")
+ buf.write("\2\2\u00af\u00ad\3\2\2\2\u00b0\u00b1\7\61\2\2\u00b1\u00b2")
+ buf.write("\7,\2\2\u00b2\u00b3\7#\2\2\u00b3\u00b7\3\2\2\2\u00b4\u00b6")
+ buf.write("\13\2\2\2\u00b5\u00b4\3\2\2\2\u00b6\u00b9\3\2\2\2\u00b7")
+ buf.write("\u00b8\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b8\u00ba\3\2\2\2")
+ buf.write("\u00b9\u00b7\3\2\2\2\u00ba\u00bb\7,\2\2\u00bb\u00bc\7")
+ buf.write("\61\2\2\u00bc\62\3\2\2\2\u00bd\u00bf\t\6\2\2\u00be\u00bd")
+ buf.write("\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00be\3\2\2\2\u00c0")
+ buf.write("\u00c1\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00c3\b\32\2")
+ buf.write("\2\u00c3\64\3\2\2\2\u00c4\u00c5\7\61\2\2\u00c5\u00c6\7")
+ buf.write("\61\2\2\u00c6\u00ca\3\2\2\2\u00c7\u00c9\n\7\2\2\u00c8")
+ buf.write("\u00c7\3\2\2\2\u00c9\u00cc\3\2\2\2\u00ca\u00c8\3\2\2\2")
+ buf.write("\u00ca\u00cb\3\2\2\2\u00cb\u00cd\3\2\2\2\u00cc\u00ca\3")
+ buf.write("\2\2\2\u00cd\u00ce\b\33\2\2\u00ce\66\3\2\2\2\u00cf\u00d0")
+ buf.write("\7\61\2\2\u00d0\u00d1\7,\2\2\u00d1\u00d5\3\2\2\2\u00d2")
+ buf.write("\u00d4\13\2\2\2\u00d3\u00d2\3\2\2\2\u00d4\u00d7\3\2\2")
+ buf.write("\2\u00d5\u00d6\3\2\2\2\u00d5\u00d3\3\2\2\2\u00d6\u00d8")
+ buf.write("\3\2\2\2\u00d7\u00d5\3\2\2\2\u00d8\u00d9\7,\2\2\u00d9")
+ buf.write("\u00da\7\61\2\2\u00da\u00db\3\2\2\2\u00db\u00dc\b\34\2")
+ buf.write("\2\u00dc8\3\2\2\2\13\2\u009a\u009f\u00a7\u00ad\u00b7\u00c0")
+ buf.write("\u00ca\u00d5\3\b\2\2")
+ return buf.getvalue()
+
+
+class TLexer(Lexer):
+
+ atn = ATNDeserializer().deserialize(serializedATN())
+
+ decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
+
+
+ T__0 = 1
+ T__1 = 2
+ T__2 = 3
+ T__3 = 4
+ T__4 = 5
+ T__5 = 6
+ T__6 = 7
+ T__7 = 8
+ T__8 = 9
+ T__9 = 10
+ T__10 = 11
+ T__11 = 12
+ T__12 = 13
+ T__13 = 14
+ T__14 = 15
+ T__15 = 16
+ T__16 = 17
+ T__17 = 18
+ T__18 = 19
+ T__19 = 20
+ INTCONSTANT = 21
+ HEXCONSTANT = 22
+ IDENTIFIER = 23
+ DOCCOMMENT = 24
+ WHITESPACE = 25
+ COMMENT = 26
+ MULTICOMM = 27
+
+ modeNames = [ "DEFAULT_MODE" ]
+
+ literalNames = [ "<INVALID>",
+ "'import'", "';'", "'package'", "'service'", "'{'", "'}'", "'event'",
+ "'void'", "'('", "')'", "'readonly'", "','", "'bool'", "'int'",
+ "'real'", "'string'", "'struct'", "'enum'", "'flags'", "'='" ]
+
+ symbolicNames = [ "<INVALID>",
+ "INTCONSTANT", "HEXCONSTANT", "IDENTIFIER", "DOCCOMMENT", "WHITESPACE",
+ "COMMENT", "MULTICOMM" ]
+
+ ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6",
+ "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13",
+ "T__14", "T__15", "T__16", "T__17", "T__18", "T__19",
+ "INTCONSTANT", "HEXCONSTANT", "IDENTIFIER", "DOCCOMMENT",
+ "WHITESPACE", "COMMENT", "MULTICOMM" ]
+
+ grammarFileName = "T.g4"
+
+ def __init__(self, input=None):
+ super().__init__(input)
+ self.checkVersion("4.5.2")
+ self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
+ self._actions = None
+ self._predicates = None
+
+
diff --git a/qif/idl/parser/TLexer.tokens b/qif/idl/parser/TLexer.tokens
new file mode 100644
index 0000000..c9d702b
--- /dev/null
+++ b/qif/idl/parser/TLexer.tokens
@@ -0,0 +1,47 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+T__13=14
+T__14=15
+T__15=16
+T__16=17
+T__17=18
+T__18=19
+T__19=20
+INTCONSTANT=21
+HEXCONSTANT=22
+IDENTIFIER=23
+DOCCOMMENT=24
+WHITESPACE=25
+COMMENT=26
+MULTICOMM=27
+'import'=1
+';'=2
+'package'=3
+'service'=4
+'{'=5
+'}'=6
+'event'=7
+'void'=8
+'('=9
+')'=10
+'readonly'=11
+','=12
+'bool'=13
+'int'=14
+'real'=15
+'string'=16
+'struct'=17
+'enum'=18
+'flags'=19
+'='=20
diff --git a/qif/idl/parser/TListener.py b/qif/idl/parser/TListener.py
new file mode 100644
index 0000000..dd70d73
--- /dev/null
+++ b/qif/idl/parser/TListener.py
@@ -0,0 +1,181 @@
+# Generated from T.g4 by ANTLR 4.5.2
+from antlr4 import *
+if __name__ is not None and "." in __name__:
+ from .TParser import TParser
+else:
+ from TParser import TParser
+
+# This class defines a complete listener for a parse tree produced by TParser.
+class TListener(ParseTreeListener):
+
+ # Enter a parse tree produced by TParser#documentSymbol.
+ def enterDocumentSymbol(self, ctx:TParser.DocumentSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#documentSymbol.
+ def exitDocumentSymbol(self, ctx:TParser.DocumentSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#headerSymbol.
+ def enterHeaderSymbol(self, ctx:TParser.HeaderSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#headerSymbol.
+ def exitHeaderSymbol(self, ctx:TParser.HeaderSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#importSymbol.
+ def enterImportSymbol(self, ctx:TParser.ImportSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#importSymbol.
+ def exitImportSymbol(self, ctx:TParser.ImportSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#packageSymbol.
+ def enterPackageSymbol(self, ctx:TParser.PackageSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#packageSymbol.
+ def exitPackageSymbol(self, ctx:TParser.PackageSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#definitionSymbol.
+ def enterDefinitionSymbol(self, ctx:TParser.DefinitionSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#definitionSymbol.
+ def exitDefinitionSymbol(self, ctx:TParser.DefinitionSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#serviceSymbol.
+ def enterServiceSymbol(self, ctx:TParser.ServiceSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#serviceSymbol.
+ def exitServiceSymbol(self, ctx:TParser.ServiceSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#memberSymbol.
+ def enterMemberSymbol(self, ctx:TParser.MemberSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#memberSymbol.
+ def exitMemberSymbol(self, ctx:TParser.MemberSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#operationSymbol.
+ def enterOperationSymbol(self, ctx:TParser.OperationSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#operationSymbol.
+ def exitOperationSymbol(self, ctx:TParser.OperationSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#attributeSymbol.
+ def enterAttributeSymbol(self, ctx:TParser.AttributeSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#attributeSymbol.
+ def exitAttributeSymbol(self, ctx:TParser.AttributeSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#parameterSymbol.
+ def enterParameterSymbol(self, ctx:TParser.ParameterSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#parameterSymbol.
+ def exitParameterSymbol(self, ctx:TParser.ParameterSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#typeSymbol.
+ def enterTypeSymbol(self, ctx:TParser.TypeSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#typeSymbol.
+ def exitTypeSymbol(self, ctx:TParser.TypeSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#complexTypeSymbol.
+ def enterComplexTypeSymbol(self, ctx:TParser.ComplexTypeSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#complexTypeSymbol.
+ def exitComplexTypeSymbol(self, ctx:TParser.ComplexTypeSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#primitiveTypeSymbol.
+ def enterPrimitiveTypeSymbol(self, ctx:TParser.PrimitiveTypeSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#primitiveTypeSymbol.
+ def exitPrimitiveTypeSymbol(self, ctx:TParser.PrimitiveTypeSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#structSymbol.
+ def enterStructSymbol(self, ctx:TParser.StructSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#structSymbol.
+ def exitStructSymbol(self, ctx:TParser.StructSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#structMemberSymbol.
+ def enterStructMemberSymbol(self, ctx:TParser.StructMemberSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#structMemberSymbol.
+ def exitStructMemberSymbol(self, ctx:TParser.StructMemberSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#enumSymbol.
+ def enterEnumSymbol(self, ctx:TParser.EnumSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#enumSymbol.
+ def exitEnumSymbol(self, ctx:TParser.EnumSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#enumType.
+ def enterEnumType(self, ctx:TParser.EnumTypeContext):
+ pass
+
+ # Exit a parse tree produced by TParser#enumType.
+ def exitEnumType(self, ctx:TParser.EnumTypeContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#enumMemberSymbol.
+ def enterEnumMemberSymbol(self, ctx:TParser.EnumMemberSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#enumMemberSymbol.
+ def exitEnumMemberSymbol(self, ctx:TParser.EnumMemberSymbolContext):
+ pass
+
+
+ # Enter a parse tree produced by TParser#intSymbol.
+ def enterIntSymbol(self, ctx:TParser.IntSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#intSymbol.
+ def exitIntSymbol(self, ctx:TParser.IntSymbolContext):
+ pass
+
+
diff --git a/qif/idl/parser/TParser.py b/qif/idl/parser/TParser.py
new file mode 100644
index 0000000..6477fe4
--- /dev/null
+++ b/qif/idl/parser/TParser.py
@@ -0,0 +1,1475 @@
+# Generated from T.g4 by ANTLR 4.5.2
+# encoding: utf-8
+from antlr4 import *
+from io import StringIO
+
+def serializedATN():
+ with StringIO() as buf:
+ buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\35")
+ buf.write("\u00be\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
+ buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
+ buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23")
+ buf.write("\4\24\t\24\3\2\3\2\7\2+\n\2\f\2\16\2.\13\2\3\3\3\3\7\3")
+ buf.write("\62\n\3\f\3\16\3\65\13\3\3\4\3\4\3\4\3\4\3\5\5\5<\n\5")
+ buf.write("\3\5\3\5\3\5\3\5\3\6\3\6\3\6\5\6E\n\6\3\7\5\7H\n\7\3\7")
+ buf.write("\3\7\3\7\3\7\7\7N\n\7\f\7\16\7Q\13\7\3\7\3\7\3\b\3\b\5")
+ buf.write("\bW\n\b\3\t\5\tZ\n\t\3\t\5\t]\n\t\3\t\3\t\5\ta\n\t\3\t")
+ buf.write("\3\t\3\t\7\tf\n\t\f\t\16\ti\13\t\3\t\3\t\3\t\3\n\5\no")
+ buf.write("\n\n\3\n\5\nr\n\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\5\13")
+ buf.write("{\n\13\3\f\3\f\5\f\177\n\f\3\r\3\r\3\16\3\16\3\16\3\16")
+ buf.write("\5\16\u0087\n\16\3\17\5\17\u008a\n\17\3\17\3\17\3\17\3")
+ buf.write("\17\7\17\u0090\n\17\f\17\16\17\u0093\13\17\3\17\3\17\3")
+ buf.write("\20\5\20\u0098\n\20\3\20\3\20\3\20\5\20\u009d\n\20\3\21")
+ buf.write("\5\21\u00a0\n\21\3\21\3\21\3\21\3\21\7\21\u00a6\n\21\f")
+ buf.write("\21\16\21\u00a9\13\21\3\21\3\21\3\22\3\22\5\22\u00af\n")
+ buf.write("\22\3\23\5\23\u00b2\n\23\3\23\3\23\3\23\3\23\5\23\u00b8")
+ buf.write("\n\23\3\24\3\24\5\24\u00bc\n\24\3\24\2\2\25\2\4\6\b\n")
+ buf.write("\f\16\20\22\24\26\30\32\34\36 \"$&\2\2\u00c7\2(\3\2\2")
+ buf.write("\2\4/\3\2\2\2\6\66\3\2\2\2\b;\3\2\2\2\nD\3\2\2\2\fG\3")
+ buf.write("\2\2\2\16V\3\2\2\2\20Y\3\2\2\2\22n\3\2\2\2\24w\3\2\2\2")
+ buf.write("\26~\3\2\2\2\30\u0080\3\2\2\2\32\u0086\3\2\2\2\34\u0089")
+ buf.write("\3\2\2\2\36\u0097\3\2\2\2 \u009f\3\2\2\2\"\u00ae\3\2\2")
+ buf.write("\2$\u00b1\3\2\2\2&\u00bb\3\2\2\2(,\5\4\3\2)+\5\n\6\2*")
+ buf.write(")\3\2\2\2+.\3\2\2\2,*\3\2\2\2,-\3\2\2\2-\3\3\2\2\2.,\3")
+ buf.write("\2\2\2/\63\5\b\5\2\60\62\5\6\4\2\61\60\3\2\2\2\62\65\3")
+ buf.write("\2\2\2\63\61\3\2\2\2\63\64\3\2\2\2\64\5\3\2\2\2\65\63")
+ buf.write("\3\2\2\2\66\67\7\3\2\2\678\7\31\2\289\7\4\2\29\7\3\2\2")
+ buf.write("\2:<\7\32\2\2;:\3\2\2\2;<\3\2\2\2<=\3\2\2\2=>\7\5\2\2")
+ buf.write(">?\7\31\2\2?@\7\4\2\2@\t\3\2\2\2AE\5\f\7\2BE\5\34\17\2")
+ buf.write("CE\5 \21\2DA\3\2\2\2DB\3\2\2\2DC\3\2\2\2E\13\3\2\2\2F")
+ buf.write("H\7\32\2\2GF\3\2\2\2GH\3\2\2\2HI\3\2\2\2IJ\7\6\2\2JK\7")
+ buf.write("\31\2\2KO\7\7\2\2LN\5\16\b\2ML\3\2\2\2NQ\3\2\2\2OM\3\2")
+ buf.write("\2\2OP\3\2\2\2PR\3\2\2\2QO\3\2\2\2RS\7\b\2\2S\r\3\2\2")
+ buf.write("\2TW\5\20\t\2UW\5\22\n\2VT\3\2\2\2VU\3\2\2\2W\17\3\2\2")
+ buf.write("\2XZ\7\32\2\2YX\3\2\2\2YZ\3\2\2\2Z\\\3\2\2\2[]\7\t\2\2")
+ buf.write("\\[\3\2\2\2\\]\3\2\2\2]`\3\2\2\2^a\5\26\f\2_a\7\n\2\2")
+ buf.write("`^\3\2\2\2`_\3\2\2\2ab\3\2\2\2bc\7\31\2\2cg\7\13\2\2d")
+ buf.write("f\5\24\13\2ed\3\2\2\2fi\3\2\2\2ge\3\2\2\2gh\3\2\2\2hj")
+ buf.write("\3\2\2\2ig\3\2\2\2jk\7\f\2\2kl\7\4\2\2l\21\3\2\2\2mo\7")
+ buf.write("\32\2\2nm\3\2\2\2no\3\2\2\2oq\3\2\2\2pr\7\r\2\2qp\3\2")
+ buf.write("\2\2qr\3\2\2\2rs\3\2\2\2st\5\26\f\2tu\7\31\2\2uv\7\4\2")
+ buf.write("\2v\23\3\2\2\2wx\5\26\f\2xz\7\31\2\2y{\7\16\2\2zy\3\2")
+ buf.write("\2\2z{\3\2\2\2{\25\3\2\2\2|\177\5\32\16\2}\177\5\30\r")
+ buf.write("\2~|\3\2\2\2~}\3\2\2\2\177\27\3\2\2\2\u0080\u0081\7\31")
+ buf.write("\2\2\u0081\31\3\2\2\2\u0082\u0087\7\17\2\2\u0083\u0087")
+ buf.write("\7\20\2\2\u0084\u0087\7\21\2\2\u0085\u0087\7\22\2\2\u0086")
+ buf.write("\u0082\3\2\2\2\u0086\u0083\3\2\2\2\u0086\u0084\3\2\2\2")
+ buf.write("\u0086\u0085\3\2\2\2\u0087\33\3\2\2\2\u0088\u008a\7\32")
+ buf.write("\2\2\u0089\u0088\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u008b")
+ buf.write("\3\2\2\2\u008b\u008c\7\23\2\2\u008c\u008d\7\31\2\2\u008d")
+ buf.write("\u0091\7\7\2\2\u008e\u0090\5\36\20\2\u008f\u008e\3\2\2")
+ buf.write("\2\u0090\u0093\3\2\2\2\u0091\u008f\3\2\2\2\u0091\u0092")
+ buf.write("\3\2\2\2\u0092\u0094\3\2\2\2\u0093\u0091\3\2\2\2\u0094")
+ buf.write("\u0095\7\b\2\2\u0095\35\3\2\2\2\u0096\u0098\7\32\2\2\u0097")
+ buf.write("\u0096\3\2\2\2\u0097\u0098\3\2\2\2\u0098\u0099\3\2\2\2")
+ buf.write("\u0099\u009a\5\26\f\2\u009a\u009c\7\31\2\2\u009b\u009d")
+ buf.write("\7\4\2\2\u009c\u009b\3\2\2\2\u009c\u009d\3\2\2\2\u009d")
+ buf.write("\37\3\2\2\2\u009e\u00a0\7\32\2\2\u009f\u009e\3\2\2\2\u009f")
+ buf.write("\u00a0\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1\u00a2\5\"\22")
+ buf.write("\2\u00a2\u00a3\7\31\2\2\u00a3\u00a7\7\7\2\2\u00a4\u00a6")
+ buf.write("\5$\23\2\u00a5\u00a4\3\2\2\2\u00a6\u00a9\3\2\2\2\u00a7")
+ buf.write("\u00a5\3\2\2\2\u00a7\u00a8\3\2\2\2\u00a8\u00aa\3\2\2\2")
+ buf.write("\u00a9\u00a7\3\2\2\2\u00aa\u00ab\7\b\2\2\u00ab!\3\2\2")
+ buf.write("\2\u00ac\u00af\7\24\2\2\u00ad\u00af\7\25\2\2\u00ae\u00ac")
+ buf.write("\3\2\2\2\u00ae\u00ad\3\2\2\2\u00af#\3\2\2\2\u00b0\u00b2")
+ buf.write("\7\32\2\2\u00b1\u00b0\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2")
+ buf.write("\u00b3\3\2\2\2\u00b3\u00b4\7\31\2\2\u00b4\u00b5\7\26\2")
+ buf.write("\2\u00b5\u00b7\5&\24\2\u00b6\u00b8\7\16\2\2\u00b7\u00b6")
+ buf.write("\3\2\2\2\u00b7\u00b8\3\2\2\2\u00b8%\3\2\2\2\u00b9\u00bc")
+ buf.write("\7\27\2\2\u00ba\u00bc\7\30\2\2\u00bb\u00b9\3\2\2\2\u00bb")
+ buf.write("\u00ba\3\2\2\2\u00bc\'\3\2\2\2\34,\63;DGOVY\\`gnqz~\u0086")
+ buf.write("\u0089\u0091\u0097\u009c\u009f\u00a7\u00ae\u00b1\u00b7")
+ buf.write("\u00bb")
+ return buf.getvalue()
+
+
+class TParser ( Parser ):
+
+ grammarFileName = "T.g4"
+
+ atn = ATNDeserializer().deserialize(serializedATN())
+
+ decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
+
+ sharedContextCache = PredictionContextCache()
+
+ literalNames = [ "<INVALID>", "'import'", "';'", "'package'", "'service'",
+ "'{'", "'}'", "'event'", "'void'", "'('", "')'", "'readonly'",
+ "','", "'bool'", "'int'", "'real'", "'string'", "'struct'",
+ "'enum'", "'flags'", "'='" ]
+
+ symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
+ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
+ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
+ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
+ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
+ "<INVALID>", "INTCONSTANT", "HEXCONSTANT", "IDENTIFIER",
+ "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ]
+
+ RULE_documentSymbol = 0
+ RULE_headerSymbol = 1
+ RULE_importSymbol = 2
+ RULE_packageSymbol = 3
+ RULE_definitionSymbol = 4
+ RULE_serviceSymbol = 5
+ RULE_memberSymbol = 6
+ RULE_operationSymbol = 7
+ RULE_attributeSymbol = 8
+ RULE_parameterSymbol = 9
+ RULE_typeSymbol = 10
+ RULE_complexTypeSymbol = 11
+ RULE_primitiveTypeSymbol = 12
+ RULE_structSymbol = 13
+ RULE_structMemberSymbol = 14
+ RULE_enumSymbol = 15
+ RULE_enumType = 16
+ RULE_enumMemberSymbol = 17
+ RULE_intSymbol = 18
+
+ ruleNames = [ "documentSymbol", "headerSymbol", "importSymbol", "packageSymbol",
+ "definitionSymbol", "serviceSymbol", "memberSymbol",
+ "operationSymbol", "attributeSymbol", "parameterSymbol",
+ "typeSymbol", "complexTypeSymbol", "primitiveTypeSymbol",
+ "structSymbol", "structMemberSymbol", "enumSymbol", "enumType",
+ "enumMemberSymbol", "intSymbol" ]
+
+ EOF = Token.EOF
+ T__0=1
+ T__1=2
+ T__2=3
+ T__3=4
+ T__4=5
+ T__5=6
+ T__6=7
+ T__7=8
+ T__8=9
+ T__9=10
+ T__10=11
+ T__11=12
+ T__12=13
+ T__13=14
+ T__14=15
+ T__15=16
+ T__16=17
+ T__17=18
+ T__18=19
+ T__19=20
+ INTCONSTANT=21
+ HEXCONSTANT=22
+ IDENTIFIER=23
+ DOCCOMMENT=24
+ WHITESPACE=25
+ COMMENT=26
+ MULTICOMM=27
+
+ def __init__(self, input:TokenStream):
+ super().__init__(input)
+ self.checkVersion("4.5.2")
+ self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
+ self._predicates = None
+
+
+
+ class DocumentSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def headerSymbol(self):
+ return self.getTypedRuleContext(TParser.HeaderSymbolContext,0)
+
+
+ def definitionSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.DefinitionSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.DefinitionSymbolContext,i)
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_documentSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterDocumentSymbol" ):
+ listener.enterDocumentSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitDocumentSymbol" ):
+ listener.exitDocumentSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitDocumentSymbol" ):
+ return visitor.visitDocumentSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def documentSymbol(self):
+
+ localctx = TParser.DocumentSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 0, self.RULE_documentSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 38
+ self.headerSymbol()
+ self.state = 42
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__3) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.DOCCOMMENT))) != 0):
+ self.state = 39
+ self.definitionSymbol()
+ self.state = 44
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class HeaderSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def packageSymbol(self):
+ return self.getTypedRuleContext(TParser.PackageSymbolContext,0)
+
+
+ def importSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.ImportSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.ImportSymbolContext,i)
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_headerSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterHeaderSymbol" ):
+ listener.enterHeaderSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitHeaderSymbol" ):
+ listener.exitHeaderSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitHeaderSymbol" ):
+ return visitor.visitHeaderSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def headerSymbol(self):
+
+ localctx = TParser.HeaderSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 2, self.RULE_headerSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 45
+ self.packageSymbol()
+ self.state = 49
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la==TParser.T__0:
+ self.state = 46
+ self.importSymbol()
+ self.state = 51
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ImportSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_importSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterImportSymbol" ):
+ listener.enterImportSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitImportSymbol" ):
+ listener.exitImportSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitImportSymbol" ):
+ return visitor.visitImportSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def importSymbol(self):
+
+ localctx = TParser.ImportSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 4, self.RULE_importSymbol)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 52
+ self.match(TParser.T__0)
+ self.state = 53
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 54
+ self.match(TParser.T__1)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class PackageSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_packageSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterPackageSymbol" ):
+ listener.enterPackageSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitPackageSymbol" ):
+ listener.exitPackageSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitPackageSymbol" ):
+ return visitor.visitPackageSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def packageSymbol(self):
+
+ localctx = TParser.PackageSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 6, self.RULE_packageSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 57
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 56
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 59
+ self.match(TParser.T__2)
+ self.state = 60
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 61
+ self.match(TParser.T__1)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DefinitionSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def serviceSymbol(self):
+ return self.getTypedRuleContext(TParser.ServiceSymbolContext,0)
+
+
+ def structSymbol(self):
+ return self.getTypedRuleContext(TParser.StructSymbolContext,0)
+
+
+ def enumSymbol(self):
+ return self.getTypedRuleContext(TParser.EnumSymbolContext,0)
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_definitionSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterDefinitionSymbol" ):
+ listener.enterDefinitionSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitDefinitionSymbol" ):
+ listener.exitDefinitionSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitDefinitionSymbol" ):
+ return visitor.visitDefinitionSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def definitionSymbol(self):
+
+ localctx = TParser.DefinitionSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 8, self.RULE_definitionSymbol)
+ try:
+ self.state = 66
+ self._errHandler.sync(self);
+ la_ = self._interp.adaptivePredict(self._input,3,self._ctx)
+ if la_ == 1:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 63
+ self.serviceSymbol()
+ pass
+
+ elif la_ == 2:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 64
+ self.structSymbol()
+ pass
+
+ elif la_ == 3:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 65
+ self.enumSymbol()
+ pass
+
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ServiceSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def memberSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.MemberSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.MemberSymbolContext,i)
+
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_serviceSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterServiceSymbol" ):
+ listener.enterServiceSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitServiceSymbol" ):
+ listener.exitServiceSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitServiceSymbol" ):
+ return visitor.visitServiceSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def serviceSymbol(self):
+
+ localctx = TParser.ServiceSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 10, self.RULE_serviceSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 69
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 68
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 71
+ self.match(TParser.T__3)
+ self.state = 72
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 73
+ self.match(TParser.T__4)
+ self.state = 77
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__6) | (1 << TParser.T__7) | (1 << TParser.T__10) | (1 << TParser.T__12) | (1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ self.state = 74
+ self.memberSymbol()
+ self.state = 79
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 80
+ self.match(TParser.T__5)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class MemberSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def operationSymbol(self):
+ return self.getTypedRuleContext(TParser.OperationSymbolContext,0)
+
+
+ def attributeSymbol(self):
+ return self.getTypedRuleContext(TParser.AttributeSymbolContext,0)
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_memberSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterMemberSymbol" ):
+ listener.enterMemberSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitMemberSymbol" ):
+ listener.exitMemberSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitMemberSymbol" ):
+ return visitor.visitMemberSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def memberSymbol(self):
+
+ localctx = TParser.MemberSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 12, self.RULE_memberSymbol)
+ try:
+ self.state = 84
+ self._errHandler.sync(self);
+ la_ = self._interp.adaptivePredict(self._input,6,self._ctx)
+ if la_ == 1:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 82
+ self.operationSymbol()
+ pass
+
+ elif la_ == 2:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 83
+ self.attributeSymbol()
+ pass
+
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class OperationSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.isEvent = None # Token
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def typeSymbol(self):
+ return self.getTypedRuleContext(TParser.TypeSymbolContext,0)
+
+
+ def parameterSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.ParameterSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.ParameterSymbolContext,i)
+
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_operationSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterOperationSymbol" ):
+ listener.enterOperationSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitOperationSymbol" ):
+ listener.exitOperationSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitOperationSymbol" ):
+ return visitor.visitOperationSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def operationSymbol(self):
+
+ localctx = TParser.OperationSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 14, self.RULE_operationSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 87
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 86
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 90
+ _la = self._input.LA(1)
+ if _la==TParser.T__6:
+ self.state = 89
+ localctx.isEvent = self.match(TParser.T__6)
+
+
+ self.state = 94
+ token = self._input.LA(1)
+ if token in [TParser.T__12, TParser.T__13, TParser.T__14, TParser.T__15, TParser.IDENTIFIER]:
+ self.state = 92
+ self.typeSymbol()
+
+ elif token in [TParser.T__7]:
+ self.state = 93
+ self.match(TParser.T__7)
+
+ else:
+ raise NoViableAltException(self)
+
+ self.state = 96
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 97
+ self.match(TParser.T__8)
+ self.state = 101
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__12) | (1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.IDENTIFIER))) != 0):
+ self.state = 98
+ self.parameterSymbol()
+ self.state = 103
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 104
+ self.match(TParser.T__9)
+ self.state = 105
+ self.match(TParser.T__1)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class AttributeSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.isReadOnly = None # Token
+ self.name = None # Token
+
+ def typeSymbol(self):
+ return self.getTypedRuleContext(TParser.TypeSymbolContext,0)
+
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_attributeSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterAttributeSymbol" ):
+ listener.enterAttributeSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitAttributeSymbol" ):
+ listener.exitAttributeSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitAttributeSymbol" ):
+ return visitor.visitAttributeSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def attributeSymbol(self):
+
+ localctx = TParser.AttributeSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 16, self.RULE_attributeSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 108
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 107
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 111
+ _la = self._input.LA(1)
+ if _la==TParser.T__10:
+ self.state = 110
+ localctx.isReadOnly = self.match(TParser.T__10)
+
+
+ self.state = 113
+ self.typeSymbol()
+ self.state = 114
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 115
+ self.match(TParser.T__1)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ParameterSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.name = None # Token
+
+ def typeSymbol(self):
+ return self.getTypedRuleContext(TParser.TypeSymbolContext,0)
+
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_parameterSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterParameterSymbol" ):
+ listener.enterParameterSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitParameterSymbol" ):
+ listener.exitParameterSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitParameterSymbol" ):
+ return visitor.visitParameterSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def parameterSymbol(self):
+
+ localctx = TParser.ParameterSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 18, self.RULE_parameterSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 117
+ self.typeSymbol()
+ self.state = 118
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 120
+ _la = self._input.LA(1)
+ if _la==TParser.T__11:
+ self.state = 119
+ self.match(TParser.T__11)
+
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class TypeSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def primitiveTypeSymbol(self):
+ return self.getTypedRuleContext(TParser.PrimitiveTypeSymbolContext,0)
+
+
+ def complexTypeSymbol(self):
+ return self.getTypedRuleContext(TParser.ComplexTypeSymbolContext,0)
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_typeSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterTypeSymbol" ):
+ listener.enterTypeSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitTypeSymbol" ):
+ listener.exitTypeSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitTypeSymbol" ):
+ return visitor.visitTypeSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def typeSymbol(self):
+
+ localctx = TParser.TypeSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 20, self.RULE_typeSymbol)
+ try:
+ self.state = 124
+ token = self._input.LA(1)
+ if token in [TParser.T__12, TParser.T__13, TParser.T__14, TParser.T__15]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 122
+ self.primitiveTypeSymbol()
+
+ elif token in [TParser.IDENTIFIER]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 123
+ self.complexTypeSymbol()
+
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ComplexTypeSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_complexTypeSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterComplexTypeSymbol" ):
+ listener.enterComplexTypeSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitComplexTypeSymbol" ):
+ listener.exitComplexTypeSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitComplexTypeSymbol" ):
+ return visitor.visitComplexTypeSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def complexTypeSymbol(self):
+
+ localctx = TParser.ComplexTypeSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 22, self.RULE_complexTypeSymbol)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 126
+ localctx.name = self.match(TParser.IDENTIFIER)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class PrimitiveTypeSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.name = None # Token
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_primitiveTypeSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterPrimitiveTypeSymbol" ):
+ listener.enterPrimitiveTypeSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitPrimitiveTypeSymbol" ):
+ listener.exitPrimitiveTypeSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitPrimitiveTypeSymbol" ):
+ return visitor.visitPrimitiveTypeSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def primitiveTypeSymbol(self):
+
+ localctx = TParser.PrimitiveTypeSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 24, self.RULE_primitiveTypeSymbol)
+ try:
+ self.state = 132
+ token = self._input.LA(1)
+ if token in [TParser.T__12]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 128
+ localctx.name = self.match(TParser.T__12)
+
+ elif token in [TParser.T__13]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 129
+ localctx.name = self.match(TParser.T__13)
+
+ elif token in [TParser.T__14]:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 130
+ localctx.name = self.match(TParser.T__14)
+
+ elif token in [TParser.T__15]:
+ self.enterOuterAlt(localctx, 4)
+ self.state = 131
+ localctx.name = self.match(TParser.T__15)
+
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StructSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def structMemberSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.StructMemberSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.StructMemberSymbolContext,i)
+
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_structSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterStructSymbol" ):
+ listener.enterStructSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitStructSymbol" ):
+ listener.exitStructSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitStructSymbol" ):
+ return visitor.visitStructSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def structSymbol(self):
+
+ localctx = TParser.StructSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 26, self.RULE_structSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 135
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 134
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 137
+ self.match(TParser.T__16)
+ self.state = 138
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 139
+ self.match(TParser.T__4)
+ self.state = 143
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__12) | (1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ self.state = 140
+ self.structMemberSymbol()
+ self.state = 145
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 146
+ self.match(TParser.T__5)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StructMemberSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def typeSymbol(self):
+ return self.getTypedRuleContext(TParser.TypeSymbolContext,0)
+
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_structMemberSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterStructMemberSymbol" ):
+ listener.enterStructMemberSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitStructMemberSymbol" ):
+ listener.exitStructMemberSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitStructMemberSymbol" ):
+ return visitor.visitStructMemberSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def structMemberSymbol(self):
+
+ localctx = TParser.StructMemberSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 28, self.RULE_structMemberSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 149
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 148
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 151
+ self.typeSymbol()
+ self.state = 152
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 154
+ _la = self._input.LA(1)
+ if _la==TParser.T__1:
+ self.state = 153
+ self.match(TParser.T__1)
+
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class EnumSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def enumType(self):
+ return self.getTypedRuleContext(TParser.EnumTypeContext,0)
+
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def enumMemberSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.EnumMemberSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.EnumMemberSymbolContext,i)
+
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_enumSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterEnumSymbol" ):
+ listener.enterEnumSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitEnumSymbol" ):
+ listener.exitEnumSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitEnumSymbol" ):
+ return visitor.visitEnumSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def enumSymbol(self):
+
+ localctx = TParser.EnumSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 30, self.RULE_enumSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 157
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 156
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 159
+ self.enumType()
+ self.state = 160
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 161
+ self.match(TParser.T__4)
+ self.state = 165
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la==TParser.IDENTIFIER or _la==TParser.DOCCOMMENT:
+ self.state = 162
+ self.enumMemberSymbol()
+ self.state = 167
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 168
+ self.match(TParser.T__5)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class EnumTypeContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.isEnum = None # Token
+ self.isFlags = None # Token
+
+
+ def getRuleIndex(self):
+ return TParser.RULE_enumType
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterEnumType" ):
+ listener.enterEnumType(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitEnumType" ):
+ listener.exitEnumType(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitEnumType" ):
+ return visitor.visitEnumType(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def enumType(self):
+
+ localctx = TParser.EnumTypeContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 32, self.RULE_enumType)
+ try:
+ self.state = 172
+ token = self._input.LA(1)
+ if token in [TParser.T__17]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 170
+ localctx.isEnum = self.match(TParser.T__17)
+
+ elif token in [TParser.T__18]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 171
+ localctx.isFlags = self.match(TParser.T__18)
+
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class EnumMemberSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def intSymbol(self):
+ return self.getTypedRuleContext(TParser.IntSymbolContext,0)
+
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_enumMemberSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterEnumMemberSymbol" ):
+ listener.enterEnumMemberSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitEnumMemberSymbol" ):
+ listener.exitEnumMemberSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitEnumMemberSymbol" ):
+ return visitor.visitEnumMemberSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def enumMemberSymbol(self):
+
+ localctx = TParser.EnumMemberSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 34, self.RULE_enumMemberSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 175
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 174
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 177
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 178
+ self.match(TParser.T__19)
+ self.state = 179
+ self.intSymbol()
+ self.state = 181
+ _la = self._input.LA(1)
+ if _la==TParser.T__11:
+ self.state = 180
+ self.match(TParser.T__11)
+
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class IntSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.value = None # Token
+
+ def INTCONSTANT(self):
+ return self.getToken(TParser.INTCONSTANT, 0)
+
+ def HEXCONSTANT(self):
+ return self.getToken(TParser.HEXCONSTANT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_intSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterIntSymbol" ):
+ listener.enterIntSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitIntSymbol" ):
+ listener.exitIntSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitIntSymbol" ):
+ return visitor.visitIntSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def intSymbol(self):
+
+ localctx = TParser.IntSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 36, self.RULE_intSymbol)
+ try:
+ self.state = 185
+ token = self._input.LA(1)
+ if token in [TParser.INTCONSTANT]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 183
+ localctx.value = self.match(TParser.INTCONSTANT)
+
+ elif token in [TParser.HEXCONSTANT]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 184
+ localctx.value = self.match(TParser.HEXCONSTANT)
+
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+
+
+
+
diff --git a/qif/idl/parser/TVisitor.py b/qif/idl/parser/TVisitor.py
new file mode 100644
index 0000000..6ec784e
--- /dev/null
+++ b/qif/idl/parser/TVisitor.py
@@ -0,0 +1,108 @@
+# Generated from T.g4 by ANTLR 4.5.2
+from antlr4 import *
+if __name__ is not None and "." in __name__:
+ from .TParser import TParser
+else:
+ from TParser import TParser
+
+# This class defines a complete generic visitor for a parse tree produced by TParser.
+
+class TVisitor(ParseTreeVisitor):
+
+ # Visit a parse tree produced by TParser#documentSymbol.
+ def visitDocumentSymbol(self, ctx:TParser.DocumentSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#headerSymbol.
+ def visitHeaderSymbol(self, ctx:TParser.HeaderSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#importSymbol.
+ def visitImportSymbol(self, ctx:TParser.ImportSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#packageSymbol.
+ def visitPackageSymbol(self, ctx:TParser.PackageSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#definitionSymbol.
+ def visitDefinitionSymbol(self, ctx:TParser.DefinitionSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#serviceSymbol.
+ def visitServiceSymbol(self, ctx:TParser.ServiceSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#memberSymbol.
+ def visitMemberSymbol(self, ctx:TParser.MemberSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#operationSymbol.
+ def visitOperationSymbol(self, ctx:TParser.OperationSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#attributeSymbol.
+ def visitAttributeSymbol(self, ctx:TParser.AttributeSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#parameterSymbol.
+ def visitParameterSymbol(self, ctx:TParser.ParameterSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#typeSymbol.
+ def visitTypeSymbol(self, ctx:TParser.TypeSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#complexTypeSymbol.
+ def visitComplexTypeSymbol(self, ctx:TParser.ComplexTypeSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#primitiveTypeSymbol.
+ def visitPrimitiveTypeSymbol(self, ctx:TParser.PrimitiveTypeSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#structSymbol.
+ def visitStructSymbol(self, ctx:TParser.StructSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#structMemberSymbol.
+ def visitStructMemberSymbol(self, ctx:TParser.StructMemberSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#enumSymbol.
+ def visitEnumSymbol(self, ctx:TParser.EnumSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#enumType.
+ def visitEnumType(self, ctx:TParser.EnumTypeContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#enumMemberSymbol.
+ def visitEnumMemberSymbol(self, ctx:TParser.EnumMemberSymbolContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TParser#intSymbol.
+ def visitIntSymbol(self, ctx:TParser.IntSymbolContext):
+ return self.visitChildren(ctx)
+
+
+
+del TParser \ No newline at end of file
diff --git a/qif/idl/parser/__init__.py b/qif/idl/parser/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/qif/idl/parser/__init__.py
diff --git a/templates/packages.csv b/templates/packages.csv
new file mode 100644
index 0000000..d316387
--- /dev/null
+++ b/templates/packages.csv
@@ -0,0 +1,11 @@
+{% for package in system.packages %}
+ {%- for service in package.services -%}
+ {{package}}.{{service}}, SERVICE
+ {% endfor -%}
+ {%- for struct in package.structs -%}
+ {{package}}.{{struct}}, STRUCT
+ {% endfor -%}
+ {%- for enum in package.enums -%}
+ {{package}}.{{enum}}, ENUM
+ {% endfor -%}
+{% endfor %}
diff --git a/templates/service.tpl.cpp b/templates/service.tpl.cpp
new file mode 100644
index 0000000..0f3e788
--- /dev/null
+++ b/templates/service.tpl.cpp
@@ -0,0 +1,44 @@
+{%- macro parameterType(symbol) -%}
+ {%- if symbol.type.is_void or symbol.type.is_primitive -%}
+ {{ symbol.type }} {{symbol}}
+ {%- else -%}
+ const {{ symbol.type }} &{{symbol}}
+ {%- endif -%}
+{%- endmacro -%}
+
+# pragma once
+
+#include <{{service|lower}}.h>
+
+{{service.comment}}
+{{service}}::{{service}}(QObject *parent)
+ : QObject(parent)
+{
+}
+
+{% for attribute in service.attributes %}
+void {{service}}::set{{attribute|upperfirst}}({{ attribute|parameterType }})
+{
+ if(m_{{attribute}} == {{attribute}}) {
+ return;
+ }
+ m_{{attribute}} = {{attribute}};
+ emit {{attribute}}Changed({{attribute}});
+}
+
+{{attribute|returnType}} {{service}}::{{attribute}}() const
+{
+ return m_{{attribute}};
+}
+
+{% endfor %}
+
+{% for operation in service.operations %}
+{{operation.comment}}
+virtual {{operation.type}} {{service}}::{{operation}}()
+{
+}
+
+{% endfor %}
+
+
diff --git a/templates/service.tpl.h b/templates/service.tpl.h
new file mode 100644
index 0000000..3867c3d
--- /dev/null
+++ b/templates/service.tpl.h
@@ -0,0 +1,29 @@
+# pragma once
+
+#include <QtCore>
+
+class {{service}} : public QObject
+{
+ Q_OBJECT
+{% for attribute in service.attributes %}
+ Q_PROPERTY({{attribute}} READ {{attribute}} NOTIFY {{attribute}}Changed)
+{% endfor %}
+public:
+ {{service}}(QObject *parent=0);
+{% for operation in service.operations %}
+ Q_INVOKABLE {{operation|returnType}} {{operation}}();
+{% endfor %}
+{% for attribute in service.attributes %}
+ void set{{attribute|upperfirst}}({{ attribute|parameterType }});
+ {{attribute|returnType}} {{attribute}}() const;
+
+{% endfor %}
+Q_SIGNALS:
+{% for attribute in service.attributes %}
+ void {{attribute}}Changed({{attribute|parameterType}})
+{% endfor %}
+private:
+{% for attribute in service.attributes %}
+ m_{{attribute}};
+{% endfor %}
+};
diff --git a/templates/services.pro b/templates/services.pro
new file mode 100644
index 0000000..2f71035
--- /dev/null
+++ b/templates/services.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+SOURCES += \
+{% for service in package.services %}
+ {{service|lower}}.cpp
+{% endfor %}
+
+HEADERS += \
+{% for service in package.services %}
+ {{service|lower}}.h
+{% endfor %}
diff --git a/tests/test_climate.py b/tests/test_climate.py
new file mode 100644
index 0000000..5e628e4
--- /dev/null
+++ b/tests/test_climate.py
@@ -0,0 +1,29 @@
+from qif.idl.domain import System
+from qif.generator import FileSystem, Generator
+import logging
+import logging.config
+from pathlib import Path
+
+# logging.config.fileConfig('logging.ini')
+logging.basicConfig()
+
+log = logging.getLogger(__name__)
+
+examples = Path('./examples')
+log.debug('examples folder: {0}'.format(examples.absolute()))
+
+
+def load_system():
+ path = examples / 'climate.qif'
+ return FileSystem.parse_document(path)
+
+
+def test_service():
+ system = load_system()
+ service = system.lookup_service('vehicle.climate.ClimateControl')
+ assert service.name == 'ClimateControl'
+
+
+
+
+
diff --git a/tests/test_generator.py b/tests/test_generator.py
new file mode 100644
index 0000000..1f86ff2
--- /dev/null
+++ b/tests/test_generator.py
@@ -0,0 +1,41 @@
+from qif.idl.domain import System
+from qif.generator import FileSystem, Generator
+import logging
+import logging.config
+from pathlib import Path
+
+# logging.config.fileConfig('logging.ini')
+logging.basicConfig()
+
+log = logging.getLogger(__name__)
+
+examples = Path('./examples')
+log.debug('examples folder: {0}'.format(examples.absolute()))
+
+
+def loadSystem():
+ path = examples / 'tuner.qif'
+ return FileSystem.parse_document(path)
+
+
+def test_gen_package():
+ system = loadSystem()
+ gen = Generator()
+ template = "{{package}}"
+ package = system.lookup_package('entertainment.tuner')
+ text = gen.apply(template, {"package": package})
+ assert text == 'entertainment.tuner'
+
+
+def test_gen_service():
+ system = loadSystem()
+ gen = Generator()
+ template = """
+ {%- for service in package.services -%}
+ {{service}}
+ {%- endfor -%}
+ """
+ package = system.lookup_package('entertainment.tuner')
+ text = gen.apply(template, {"package": package})
+ assert text == 'Tuner'
+
diff --git a/tests/test_parser.py b/tests/test_parser.py
new file mode 100644
index 0000000..b6796ee
--- /dev/null
+++ b/tests/test_parser.py
@@ -0,0 +1,81 @@
+from qif.idl.domain import System
+from qif.generator import FileSystem
+import logging
+import logging.config
+from pathlib import Path
+
+# logging.config.fileConfig('logging.ini')
+logging.basicConfig()
+
+log = logging.getLogger(__name__)
+
+examples = Path('./examples')
+log.debug('examples folder: {0}'.format(examples.absolute()))
+
+
+def test_parse():
+ log.debug('test parse')
+ names = FileSystem.find_files(examples, '*.qif')
+ # import pdb; pdb.set_trace()
+ system = System()
+ for name in names:
+ log.debug('name: {0}'.format(name))
+ FileSystem.parse_document(name, system)
+
+
+def test_package():
+ path = examples / 'tuner.qif'
+ system = FileSystem.parse_document(path)
+ assert len(system.packages) == 1
+ package = system.lookup_package('entertainment.tuner')
+ assert package in system.packages.values()
+
+
+def test_service():
+ path = examples / 'tuner.qif'
+ system = FileSystem.parse_document(path)
+ package = system.lookup_package('entertainment.tuner')
+ service = system.lookup_service('entertainment.tuner.Tuner')
+ assert service in package.services.values()
+ assert service.comment == '/*! Service Tuner */'
+
+
+def test_attribute():
+ path = examples / 'tuner.qif'
+ system = FileSystem.parse_document(path)
+ service = system.lookup_service('entertainment.tuner.Tuner')
+ package = system.lookup_package('entertainment.tuner')
+ attr = service.attributes['currentStation']
+ assert attr.type.name == 'Station'
+ assert attr.package == package
+ assert attr.type.qualifiedName == 'entertainment.tuner.Station'
+ assert attr.is_readonly
+ assert attr.comment == '/*! attribute currentStation */'
+
+
+
+def test_struct():
+ path = examples / 'tuner.qif'
+ system = FileSystem.parse_document(path)
+ package = system.lookup_package('entertainment.tuner')
+ symbol = system.lookup_struct('entertainment.tuner.Station')
+ assert symbol.name == 'Station'
+ assert symbol.package == package
+ assert symbol.qualifiedName == 'entertainment.tuner.Station'
+ assert symbol.comment == '/*! struct Station */'
+
+
+def test_enum():
+ path = examples / 'tuner.qif'
+ system = FileSystem.parse_document(path)
+ definition = system.lookup_definition('entertainment.tuner.Waveband')
+ package = system.lookup_package('entertainment.tuner')
+ symbol = system.lookup_enum('entertainment.tuner.Waveband')
+ assert definition == symbol
+ assert symbol.name == 'Waveband'
+ assert symbol.package == package
+ assert symbol.qualifiedName == 'entertainment.tuner.Waveband'
+ assert symbol.comment == '/*! enum Waveband */'
+
+
+