""" GTSAM Copyright 2010-2020, Georgia Tech Research Corporation, Atlanta, Georgia 30332-0415 All Rights Reserved See LICENSE for the license information Classes and rules for parsing C++ templates and typedefs for template instantiations. Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert """ from typing import List from pyparsing import Optional, ParseResults, delimitedList from .tokens import (EQUAL, IDENT, LBRACE, LOPBRACK, RBRACE, ROPBRACK, SEMI_COLON, TEMPLATE, TYPEDEF) from .type import Typename, TemplatedType class Template: """ Rule to parse templated values in the interface file. E.g. template // this is the Template. class Camera { ... }; """ class TypenameAndInstantiations: """ Rule to parse the template parameters. template // POSE is the Instantiation. """ rule = ( IDENT("typename") # + Optional( # EQUAL # + LBRACE # + ((delimitedList(TemplatedType.rule ^ Typename.rule) ("instantiations"))) # + RBRACE # )).setParseAction(lambda t: Template.TypenameAndInstantiations( t.typename, t.instantiations)) def __init__(self, typename: str, instantiations: ParseResults): self.typename = typename self.instantiations = [] if instantiations: for inst in instantiations: x = inst.typename if isinstance(inst, TemplatedType) else inst self.instantiations.append(x) rule = ( # BR TEMPLATE # + LOPBRACK # + delimitedList(TypenameAndInstantiations.rule)( "typename_and_instantiations_list") # + ROPBRACK # BR ).setParseAction( lambda t: Template(t.typename_and_instantiations_list.asList())) def __init__( self, typename_and_instantiations_list: List[TypenameAndInstantiations]): ti_list = typename_and_instantiations_list self.typenames = [ti.typename for ti in ti_list] self.instantiations = [ti.instantiations for ti in ti_list] def __repr__(self) -> str: return "<{0}>".format(", ".join(self.typenames)) class TypedefTemplateInstantiation: """ Rule for parsing typedefs (with templates) within the interface file. E.g. ``` typedef SuperComplexName EasierName; ``` """ rule = (TYPEDEF + TemplatedType.rule("templated_type") + IDENT("new_name") + SEMI_COLON).setParseAction(lambda t: TypedefTemplateInstantiation( t.templated_type[0], t.new_name)) def __init__(self, templated_type: TemplatedType, new_name: str, parent: str = ''): self.typename = templated_type.typename self.new_name = new_name self.parent = parent def __repr__(self): return "Typedef: {new_name} = {typename}".format( new_name=self.new_name, typename=self.typename)