diff options
author | Juergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com> | 2016-08-02 12:40:57 +0200 |
---|---|---|
committer | Juergen Ryannel <juergen.bocklage-ryannel@pelagicore.com> | 2016-11-30 10:01:19 +0100 |
commit | ada58821a68c61d9bc905ce793dd4d0f6b497645 (patch) | |
tree | 4f9dede65368fcb04155fc8298f3a2381b0705b9 | |
parent | 6a3dd2248f24670ad70a28a70e848e33eac651c5 (diff) | |
download | qtivi-qface-ada58821a68c61d9bc905ce793dd4d0f6b497645.tar.gz |
initial commit
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | T.g4 | 96 | ||||
-rwxr-xr-x | cli.py | 87 | ||||
-rwxr-xr-x | cpp.py | 30 | ||||
-rwxr-xr-x | csv.py | 10 | ||||
-rw-r--r-- | examples/climate.qif | 107 | ||||
-rw-r--r-- | examples/tuner.qif | 41 | ||||
-rw-r--r-- | qif/__init__.py | 0 | ||||
-rw-r--r-- | qif/generator.py | 108 | ||||
-rw-r--r-- | qif/idl/__init__.py | 0 | ||||
-rw-r--r-- | qif/idl/domain.py | 271 | ||||
-rw-r--r-- | qif/idl/listener.py | 145 | ||||
-rw-r--r-- | qif/idl/parser/T.tokens | 47 | ||||
-rw-r--r-- | qif/idl/parser/TLexer.py | 162 | ||||
-rw-r--r-- | qif/idl/parser/TLexer.tokens | 47 | ||||
-rw-r--r-- | qif/idl/parser/TListener.py | 181 | ||||
-rw-r--r-- | qif/idl/parser/TParser.py | 1475 | ||||
-rw-r--r-- | qif/idl/parser/TVisitor.py | 108 | ||||
-rw-r--r-- | qif/idl/parser/__init__.py | 0 | ||||
-rw-r--r-- | templates/packages.csv | 11 | ||||
-rw-r--r-- | templates/service.tpl.cpp | 44 | ||||
-rw-r--r-- | templates/service.tpl.h | 29 | ||||
-rw-r--r-- | templates/services.pro | 11 | ||||
-rw-r--r-- | tests/test_climate.py | 29 | ||||
-rw-r--r-- | tests/test_generator.py | 41 | ||||
-rw-r--r-- | tests/test_parser.py | 81 |
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 @@ -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 @@ -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; @@ -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() @@ -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) @@ -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 */' + + + |