| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  | """
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-11 23:10:35 +08:00
										 |  |  | from pyparsing import Optional, ParseResults, delimitedList  # type: ignore | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | from .tokens import (EQUAL, IDENT, LBRACE, LOPBRACK, RBRACE, ROPBRACK, | 
					
						
							|  |  |  |                      SEMI_COLON, TEMPLATE, TYPEDEF) | 
					
						
							| 
									
										
										
										
											2021-07-11 23:10:35 +08:00
										 |  |  | from .type import TemplatedType, Typename | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Template: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Rule to parse templated values in the interface file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     E.g. | 
					
						
							|  |  |  |     template<POSE>  // this is the Template. | 
					
						
							|  |  |  |     class Camera { ... }; | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     class TypenameAndInstantiations: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Rule to parse the template parameters. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         template<typename POSE>  // POSE is the Instantiation. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         rule = ( | 
					
						
							|  |  |  |             IDENT("typename")  # | 
					
						
							|  |  |  |             + Optional(  # | 
					
						
							|  |  |  |                 EQUAL  # | 
					
						
							|  |  |  |                 + LBRACE  # | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  |                 + ((delimitedList(TemplatedType.rule ^ Typename.rule) | 
					
						
							|  |  |  |                     ("instantiations")))  # | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  |                 + RBRACE  # | 
					
						
							|  |  |  |             )).setParseAction(lambda t: Template.TypenameAndInstantiations( | 
					
						
							|  |  |  |                 t.typename, t.instantiations)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def __init__(self, typename: str, instantiations: ParseResults): | 
					
						
							|  |  |  |             self.typename = typename | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  |             self.instantiations = [] | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  |             if instantiations: | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  |                 for inst in instantiations: | 
					
						
							|  |  |  |                     x = inst.typename if isinstance(inst, | 
					
						
							|  |  |  |                                                     TemplatedType) else inst | 
					
						
							|  |  |  |                     self.instantiations.append(x) | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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<Arg1, Arg2, Arg3> EasierName; | 
					
						
							|  |  |  |     ``` | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  |     rule = (TYPEDEF + TemplatedType.rule("templated_type") + | 
					
						
							|  |  |  |             IDENT("new_name") + | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  |             SEMI_COLON).setParseAction(lambda t: TypedefTemplateInstantiation( | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  |                 t.templated_type[0], t.new_name)) | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  |     def __init__(self, | 
					
						
							|  |  |  |                  templated_type: TemplatedType, | 
					
						
							|  |  |  |                  new_name: str, | 
					
						
							|  |  |  |                  parent: str = ''): | 
					
						
							|  |  |  |         self.typename = templated_type.typename | 
					
						
							| 
									
										
										
										
											2021-03-25 04:14:55 +08:00
										 |  |  |         self.new_name = new_name | 
					
						
							|  |  |  |         self.parent = parent | 
					
						
							| 
									
										
										
										
											2021-04-02 11:20:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         return "Typedef: {new_name} = {typename}".format( | 
					
						
							|  |  |  |             new_name=self.new_name, typename=self.typename) |