2 GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
6 See LICENSE for the license information
8 Parser classes and rules for parsing C++ classes.
10 Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
13 from typing
import Any, Iterable, List, Union
15 from pyparsing
import ZeroOrMore
16 from pyparsing
import Literal, Optional, Word, alphas
18 from .enum
import Enum
19 from .function
import ArgumentList, ReturnType
20 from .template
import Template
21 from .tokens
import (CLASS, COLON, CONST, DUNDER, IDENT, LBRACE, LPAREN,
22 OPERATOR, RBRACE, RPAREN, SEMI_COLON, STATIC, VIRTUAL)
23 from .type
import TemplatedType, Typename
24 from .utils
import collect_namespaces
25 from .variable
import Variable
30 Rule to parse a method in a class.
35 void sayHello() const;
40 Optional(Template.rule(
"template"))
41 + ReturnType.rule(
"return_type")
44 + ArgumentList.rule(
"args_list")
46 + Optional(
CONST(
"is_const"))
48 ).setParseAction(
lambda t:
Method(t.template, t.name, t.return_type, t.
49 args_list, t.is_const))
52 template: Union[Template, Any],
54 return_type: ReturnType,
57 parent: Union[
"Class", Any] =
''):
67 """Generate the C++ code for wrapping."""
71 return "Method: {} {} {}({}){}".
format(
82 Rule to parse all the static methods in a class.
87 static void changeGreeting();
92 Optional(Template.rule(
"template"))
94 + ReturnType.rule(
"return_type")
97 + ArgumentList.rule(
"args_list")
101 lambda t:
StaticMethod(t.name, t.return_type, t.args_list, t.template))
105 return_type: ReturnType,
107 template: Union[Template, Any] =
None,
108 parent: Union[
"Class", Any] =
''):
120 """Generate the C++ code for wrapping."""
126 Rule to parse the class constructor.
127 Can have 0 or more arguments.
130 Optional(Template.rule(
"template"))
133 + ArgumentList.rule(
"args_list")
136 ).setParseAction(
lambda t:
Constructor(t.name, t.args_list, t.template))
141 template: Union[Template, Any],
142 parent: Union[
"Class", Any] =
''):
155 Rule for parsing operator overloads.
160 Vector2 operator+(const Vector2 &v) const;
164 ReturnType.rule(
"return_type")
165 + Literal(
"operator")(
"name")
168 + ArgumentList.rule(
"args_list")
172 ).setParseAction(
lambda t:
Operator(t.name, t.operator, t.return_type, t.
173 args_list, t.is_const))
178 return_type: ReturnType,
181 parent: Union[
"Class", Any] =
''):
193 raise ValueError(
"Invalid unary operator {} used for {}".
format(
197 assert 0 <=
len(args) < 2, \
198 "Operator overload should be at most 1 argument, " \
199 "{} arguments provided".
format(
len(args))
202 if len(args) == 1
and self.
operator not in (
"()",
"[]"):
203 assert args.list()[0].ctype.typename.name == return_type.type1.typename.name, \
204 "Mixed type overloading not supported. Both arg and return type must be the same."
207 return "Operator: {}{}{}({}) {}".
format(
217 """Special Python double-underscore (dunder) methods, e.g. __iter__, __contains__"""
220 + (Word(alphas))(
"name")
223 + ArgumentList.rule(
"args_list")
226 ).setParseAction(
lambda t:
DunderMethod(t.name, t.args_list))
233 return f
"DunderMethod: __{self.name}__({self.args})"
238 Rule to parse a class defined in the interface file.
250 Rule for all the members within a class.
252 rule = ZeroOrMore(DunderMethod.rule
261 def __init__(self, members: List[Union[Constructor, Method,
262 StaticMethod, Variable,
263 Operator, Enum, DunderMethod]]):
270 self.enums: List[Enum] = []
287 _parent = COLON + (TemplatedType.rule ^ Typename.rule)(
"parent_class")
289 Optional(Template.rule(
"template"))
290 + Optional(
VIRTUAL(
"is_virtual"))
295 + Members.rule(
"members")
298 ).setParseAction(
lambda t:
Class(
299 t.template, t.is_virtual, t.name, t.parent_class, t.members.ctors, t.
300 members.methods, t.members.static_methods, t.members.dunder_methods, t.
301 members.properties, t.members.operators, t.members.enums))
305 template: Union[Template,
None],
309 ctors: List[Constructor],
310 methods: List[Method],
311 static_methods: List[StaticMethod],
312 dunder_methods: List[DunderMethod],
313 properties: List[Variable],
314 operators: List[Operator],
324 parent_class = parent_class[0]
346 for ctor
in self.
ctors:
347 if ctor.name != self.
name:
348 raise ValueError(
"Error in constructor name! {} != {}".
format(
349 ctor.name, self.
name))
351 for ctor
in self.
ctors:
356 static_method.parent = self
358 dunder_method.parent = self
360 _property.parent = self
363 """Get the namespaces which this class is nested under as a list."""
367 return "Class: {self.name}".
format(self=self)