xdr_ast.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. #!/usr/bin/env python3
  2. # ex: set filetype=python:
  3. """Define and implement the Abstract Syntax Tree for the XDR language."""
  4. import sys
  5. from typing import List
  6. from dataclasses import dataclass
  7. from lark import ast_utils, Transformer
  8. from lark.tree import Meta
  9. this_module = sys.modules[__name__]
  10. big_endian = []
  11. excluded_apis = []
  12. header_name = "none"
  13. public_apis = []
  14. structs = set()
  15. pass_by_reference = set()
  16. constants = {}
  17. def xdr_quadlen(val: str) -> int:
  18. """Return integer XDR width of an XDR type"""
  19. if val in constants:
  20. octets = constants[val]
  21. else:
  22. octets = int(val)
  23. return int((octets + 3) / 4)
  24. symbolic_widths = {
  25. "void": ["XDR_void"],
  26. "bool": ["XDR_bool"],
  27. "short": ["XDR_short"],
  28. "unsigned_short": ["XDR_unsigned_short"],
  29. "int": ["XDR_int"],
  30. "unsigned_int": ["XDR_unsigned_int"],
  31. "long": ["XDR_long"],
  32. "unsigned_long": ["XDR_unsigned_long"],
  33. "hyper": ["XDR_hyper"],
  34. "unsigned_hyper": ["XDR_unsigned_hyper"],
  35. }
  36. # Numeric XDR widths are tracked in a dictionary that is keyed
  37. # by type_name because sometimes a caller has nothing more than
  38. # the type_name to use to figure out the numeric width.
  39. max_widths = {
  40. "void": 0,
  41. "bool": 1,
  42. "short": 1,
  43. "unsigned_short": 1,
  44. "int": 1,
  45. "unsigned_int": 1,
  46. "long": 1,
  47. "unsigned_long": 1,
  48. "hyper": 2,
  49. "unsigned_hyper": 2,
  50. }
  51. @dataclass
  52. class _XdrAst(ast_utils.Ast):
  53. """Base class for the XDR abstract syntax tree"""
  54. @dataclass
  55. class _XdrIdentifier(_XdrAst):
  56. """Corresponds to 'identifier' in the XDR language grammar"""
  57. symbol: str
  58. @dataclass
  59. class _XdrValue(_XdrAst):
  60. """Corresponds to 'value' in the XDR language grammar"""
  61. value: str
  62. @dataclass
  63. class _XdrConstantValue(_XdrAst):
  64. """Corresponds to 'constant' in the XDR language grammar"""
  65. value: int
  66. @dataclass
  67. class _XdrTypeSpecifier(_XdrAst):
  68. """Corresponds to 'type_specifier' in the XDR language grammar"""
  69. type_name: str
  70. c_classifier: str = ""
  71. @dataclass
  72. class _XdrDefinedType(_XdrTypeSpecifier):
  73. """Corresponds to a type defined by the input specification"""
  74. def symbolic_width(self) -> List:
  75. """Return list containing XDR width of type's components"""
  76. return [get_header_name().upper() + "_" + self.type_name + "_sz"]
  77. def __post_init__(self):
  78. if self.type_name in structs:
  79. self.c_classifier = "struct "
  80. symbolic_widths[self.type_name] = self.symbolic_width()
  81. @dataclass
  82. class _XdrBuiltInType(_XdrTypeSpecifier):
  83. """Corresponds to a built-in XDR type"""
  84. def symbolic_width(self) -> List:
  85. """Return list containing XDR width of type's components"""
  86. return symbolic_widths[self.type_name]
  87. @dataclass
  88. class _XdrDeclaration(_XdrAst):
  89. """Base class of XDR type declarations"""
  90. @dataclass
  91. class _XdrFixedLengthOpaque(_XdrDeclaration):
  92. """A fixed-length opaque declaration"""
  93. name: str
  94. size: str
  95. template: str = "fixed_length_opaque"
  96. def max_width(self) -> int:
  97. """Return width of type in XDR_UNITS"""
  98. return xdr_quadlen(self.size)
  99. def symbolic_width(self) -> List:
  100. """Return list containing XDR width of type's components"""
  101. return ["XDR_QUADLEN(" + self.size + ")"]
  102. def __post_init__(self):
  103. max_widths[self.name] = self.max_width()
  104. symbolic_widths[self.name] = self.symbolic_width()
  105. @dataclass
  106. class _XdrVariableLengthOpaque(_XdrDeclaration):
  107. """A variable-length opaque declaration"""
  108. name: str
  109. maxsize: str
  110. template: str = "variable_length_opaque"
  111. def max_width(self) -> int:
  112. """Return width of type in XDR_UNITS"""
  113. return 1 + xdr_quadlen(self.maxsize)
  114. def symbolic_width(self) -> List:
  115. """Return list containing XDR width of type's components"""
  116. widths = ["XDR_unsigned_int"]
  117. if self.maxsize != "0":
  118. widths.append("XDR_QUADLEN(" + self.maxsize + ")")
  119. return widths
  120. def __post_init__(self):
  121. max_widths[self.name] = self.max_width()
  122. symbolic_widths[self.name] = self.symbolic_width()
  123. @dataclass
  124. class _XdrString(_XdrDeclaration):
  125. """A (NUL-terminated) variable-length string declaration"""
  126. name: str
  127. maxsize: str
  128. template: str = "string"
  129. def max_width(self) -> int:
  130. """Return width of type in XDR_UNITS"""
  131. return 1 + xdr_quadlen(self.maxsize)
  132. def symbolic_width(self) -> List:
  133. """Return list containing XDR width of type's components"""
  134. widths = ["XDR_unsigned_int"]
  135. if self.maxsize != "0":
  136. widths.append("XDR_QUADLEN(" + self.maxsize + ")")
  137. return widths
  138. def __post_init__(self):
  139. max_widths[self.name] = self.max_width()
  140. symbolic_widths[self.name] = self.symbolic_width()
  141. @dataclass
  142. class _XdrFixedLengthArray(_XdrDeclaration):
  143. """A fixed-length array declaration"""
  144. name: str
  145. spec: _XdrTypeSpecifier
  146. size: str
  147. template: str = "fixed_length_array"
  148. def max_width(self) -> int:
  149. """Return width of type in XDR_UNITS"""
  150. return xdr_quadlen(self.size) * max_widths[self.spec.type_name]
  151. def symbolic_width(self) -> List:
  152. """Return list containing XDR width of type's components"""
  153. item_width = " + ".join(symbolic_widths[self.spec.type_name])
  154. return ["(" + self.size + " * (" + item_width + "))"]
  155. def __post_init__(self):
  156. max_widths[self.name] = self.max_width()
  157. symbolic_widths[self.name] = self.symbolic_width()
  158. @dataclass
  159. class _XdrVariableLengthArray(_XdrDeclaration):
  160. """A variable-length array declaration"""
  161. name: str
  162. spec: _XdrTypeSpecifier
  163. maxsize: str
  164. template: str = "variable_length_array"
  165. def max_width(self) -> int:
  166. """Return width of type in XDR_UNITS"""
  167. return 1 + (xdr_quadlen(self.maxsize) * max_widths[self.spec.type_name])
  168. def symbolic_width(self) -> List:
  169. """Return list containing XDR width of type's components"""
  170. widths = ["XDR_unsigned_int"]
  171. if self.maxsize != "0":
  172. item_width = " + ".join(symbolic_widths[self.spec.type_name])
  173. widths.append("(" + self.maxsize + " * (" + item_width + "))")
  174. return widths
  175. def __post_init__(self):
  176. max_widths[self.name] = self.max_width()
  177. symbolic_widths[self.name] = self.symbolic_width()
  178. @dataclass
  179. class _XdrOptionalData(_XdrDeclaration):
  180. """An 'optional_data' declaration"""
  181. name: str
  182. spec: _XdrTypeSpecifier
  183. template: str = "optional_data"
  184. def max_width(self) -> int:
  185. """Return width of type in XDR_UNITS"""
  186. return 1
  187. def symbolic_width(self) -> List:
  188. """Return list containing XDR width of type's components"""
  189. return ["XDR_bool"]
  190. def __post_init__(self):
  191. structs.add(self.name)
  192. pass_by_reference.add(self.name)
  193. max_widths[self.name] = self.max_width()
  194. symbolic_widths[self.name] = self.symbolic_width()
  195. @dataclass
  196. class _XdrBasic(_XdrDeclaration):
  197. """A 'basic' declaration"""
  198. name: str
  199. spec: _XdrTypeSpecifier
  200. template: str = "basic"
  201. def max_width(self) -> int:
  202. """Return width of type in XDR_UNITS"""
  203. return max_widths[self.spec.type_name]
  204. def symbolic_width(self) -> List:
  205. """Return list containing XDR width of type's components"""
  206. return symbolic_widths[self.spec.type_name]
  207. def __post_init__(self):
  208. max_widths[self.name] = self.max_width()
  209. symbolic_widths[self.name] = self.symbolic_width()
  210. @dataclass
  211. class _XdrVoid(_XdrDeclaration):
  212. """A void declaration"""
  213. name: str = "void"
  214. template: str = "void"
  215. def max_width(self) -> int:
  216. """Return width of type in XDR_UNITS"""
  217. return 0
  218. def symbolic_width(self) -> List:
  219. """Return list containing XDR width of type's components"""
  220. return []
  221. @dataclass
  222. class _XdrConstant(_XdrAst):
  223. """Corresponds to 'constant_def' in the grammar"""
  224. name: str
  225. value: str
  226. def __post_init__(self):
  227. if self.value not in constants:
  228. constants[self.name] = int(self.value, 0)
  229. @dataclass
  230. class _XdrEnumerator(_XdrAst):
  231. """An 'identifier = value' enumerator"""
  232. name: str
  233. value: str
  234. def __post_init__(self):
  235. if self.value not in constants:
  236. constants[self.name] = int(self.value, 0)
  237. @dataclass
  238. class _XdrEnum(_XdrAst):
  239. """An XDR enum definition"""
  240. name: str
  241. enumerators: List[_XdrEnumerator]
  242. def max_width(self) -> int:
  243. """Return width of type in XDR_UNITS"""
  244. return 1
  245. def symbolic_width(self) -> List:
  246. """Return list containing XDR width of type's components"""
  247. return ["XDR_int"]
  248. def __post_init__(self):
  249. max_widths[self.name] = self.max_width()
  250. symbolic_widths[self.name] = self.symbolic_width()
  251. @dataclass
  252. class _XdrStruct(_XdrAst):
  253. """An XDR struct definition"""
  254. name: str
  255. fields: List[_XdrDeclaration]
  256. def max_width(self) -> int:
  257. """Return width of type in XDR_UNITS"""
  258. width = 0
  259. for field in self.fields:
  260. width += field.max_width()
  261. return width
  262. def symbolic_width(self) -> List:
  263. """Return list containing XDR width of type's components"""
  264. widths = []
  265. for field in self.fields:
  266. widths += field.symbolic_width()
  267. return widths
  268. def __post_init__(self):
  269. structs.add(self.name)
  270. pass_by_reference.add(self.name)
  271. max_widths[self.name] = self.max_width()
  272. symbolic_widths[self.name] = self.symbolic_width()
  273. @dataclass
  274. class _XdrPointer(_XdrAst):
  275. """An XDR pointer definition"""
  276. name: str
  277. fields: List[_XdrDeclaration]
  278. def max_width(self) -> int:
  279. """Return width of type in XDR_UNITS"""
  280. width = 1
  281. for field in self.fields[0:-1]:
  282. width += field.max_width()
  283. return width
  284. def symbolic_width(self) -> List:
  285. """Return list containing XDR width of type's components"""
  286. widths = []
  287. widths += ["XDR_bool"]
  288. for field in self.fields[0:-1]:
  289. widths += field.symbolic_width()
  290. return widths
  291. def __post_init__(self):
  292. structs.add(self.name)
  293. pass_by_reference.add(self.name)
  294. max_widths[self.name] = self.max_width()
  295. symbolic_widths[self.name] = self.symbolic_width()
  296. @dataclass
  297. class _XdrTypedef(_XdrAst):
  298. """An XDR typedef"""
  299. declaration: _XdrDeclaration
  300. def max_width(self) -> int:
  301. """Return width of type in XDR_UNITS"""
  302. return self.declaration.max_width()
  303. def symbolic_width(self) -> List:
  304. """Return list containing XDR width of type's components"""
  305. return self.declaration.symbolic_width()
  306. def __post_init__(self):
  307. if isinstance(self.declaration, _XdrBasic):
  308. new_type = self.declaration
  309. if isinstance(new_type.spec, _XdrDefinedType):
  310. if new_type.spec.type_name in pass_by_reference:
  311. pass_by_reference.add(new_type.name)
  312. max_widths[new_type.name] = self.max_width()
  313. symbolic_widths[new_type.name] = self.symbolic_width()
  314. @dataclass
  315. class _XdrCaseSpec(_XdrAst):
  316. """One case in an XDR union"""
  317. values: List[str]
  318. arm: _XdrDeclaration
  319. template: str = "case_spec"
  320. @dataclass
  321. class _XdrDefaultSpec(_XdrAst):
  322. """Default case in an XDR union"""
  323. arm: _XdrDeclaration
  324. template: str = "default_spec"
  325. @dataclass
  326. class _XdrUnion(_XdrAst):
  327. """An XDR union"""
  328. name: str
  329. discriminant: _XdrDeclaration
  330. cases: List[_XdrCaseSpec]
  331. default: _XdrDeclaration
  332. def max_width(self) -> int:
  333. """Return width of type in XDR_UNITS"""
  334. max_width = 0
  335. for case in self.cases:
  336. if case.arm.max_width() > max_width:
  337. max_width = case.arm.max_width()
  338. if self.default:
  339. if self.default.arm.max_width() > max_width:
  340. max_width = self.default.arm.max_width()
  341. return 1 + max_width
  342. def symbolic_width(self) -> List:
  343. """Return list containing XDR width of type's components"""
  344. max_width = 0
  345. for case in self.cases:
  346. if case.arm.max_width() > max_width:
  347. max_width = case.arm.max_width()
  348. width = case.arm.symbolic_width()
  349. if self.default:
  350. if self.default.arm.max_width() > max_width:
  351. max_width = self.default.arm.max_width()
  352. width = self.default.arm.symbolic_width()
  353. return symbolic_widths[self.discriminant.name] + width
  354. def __post_init__(self):
  355. structs.add(self.name)
  356. pass_by_reference.add(self.name)
  357. max_widths[self.name] = self.max_width()
  358. symbolic_widths[self.name] = self.symbolic_width()
  359. @dataclass
  360. class _RpcProcedure(_XdrAst):
  361. """RPC procedure definition"""
  362. name: str
  363. number: str
  364. argument: _XdrTypeSpecifier
  365. result: _XdrTypeSpecifier
  366. @dataclass
  367. class _RpcVersion(_XdrAst):
  368. """RPC version definition"""
  369. name: str
  370. number: str
  371. procedures: List[_RpcProcedure]
  372. @dataclass
  373. class _RpcProgram(_XdrAst):
  374. """RPC program definition"""
  375. name: str
  376. number: str
  377. versions: List[_RpcVersion]
  378. @dataclass
  379. class _Pragma(_XdrAst):
  380. """Empty class for pragma directives"""
  381. @dataclass
  382. class _XdrPassthru(_XdrAst):
  383. """Passthrough line to emit verbatim in output"""
  384. content: str
  385. @dataclass
  386. class Definition(_XdrAst, ast_utils.WithMeta):
  387. """Corresponds to 'definition' in the grammar"""
  388. meta: Meta
  389. value: _XdrAst
  390. @dataclass
  391. class Specification(_XdrAst, ast_utils.AsList):
  392. """Corresponds to 'specification' in the grammar"""
  393. definitions: List[Definition]
  394. class ParseToAst(Transformer):
  395. """Functions that transform productions into AST nodes"""
  396. def identifier(self, children):
  397. """Instantiate one _XdrIdentifier object"""
  398. return _XdrIdentifier(children[0].value)
  399. def value(self, children):
  400. """Instantiate one _XdrValue object"""
  401. if isinstance(children[0], _XdrIdentifier):
  402. return _XdrValue(children[0].symbol)
  403. return _XdrValue(children[0].children[0].value)
  404. def constant(self, children):
  405. """Instantiate one _XdrConstantValue object"""
  406. match children[0].data:
  407. case "decimal_constant":
  408. value = int(children[0].children[0].value, base=10)
  409. case "hexadecimal_constant":
  410. value = int(children[0].children[0].value, base=16)
  411. case "octal_constant":
  412. value = int(children[0].children[0].value, base=8)
  413. return _XdrConstantValue(value)
  414. def type_specifier(self, children):
  415. """Instantiate one _XdrTypeSpecifier object"""
  416. if isinstance(children[0], _XdrIdentifier):
  417. name = children[0].symbol
  418. return _XdrDefinedType(type_name=name)
  419. name = children[0].data.value
  420. return _XdrBuiltInType(type_name=name)
  421. def constant_def(self, children):
  422. """Instantiate one _XdrConstant object"""
  423. name = children[0].symbol
  424. value = children[1].value
  425. return _XdrConstant(name, value)
  426. def enum(self, children):
  427. """Instantiate one _XdrEnum object"""
  428. enum_name = children[0].symbol
  429. i = 0
  430. enumerators = []
  431. body = children[1]
  432. while i < len(body.children):
  433. name = body.children[i].symbol
  434. value = body.children[i + 1].value
  435. enumerators.append(_XdrEnumerator(name, value))
  436. i = i + 2
  437. return _XdrEnum(enum_name, enumerators)
  438. def fixed_length_opaque(self, children):
  439. """Instantiate one _XdrFixedLengthOpaque declaration object"""
  440. name = children[0].symbol
  441. size = children[1].value
  442. return _XdrFixedLengthOpaque(name, size)
  443. def variable_length_opaque(self, children):
  444. """Instantiate one _XdrVariableLengthOpaque declaration object"""
  445. name = children[0].symbol
  446. if children[1] is not None:
  447. maxsize = children[1].value
  448. else:
  449. maxsize = "0"
  450. return _XdrVariableLengthOpaque(name, maxsize)
  451. def string(self, children):
  452. """Instantiate one _XdrString declaration object"""
  453. name = children[0].symbol
  454. if children[1] is not None:
  455. maxsize = children[1].value
  456. else:
  457. maxsize = "0"
  458. return _XdrString(name, maxsize)
  459. def fixed_length_array(self, children):
  460. """Instantiate one _XdrFixedLengthArray declaration object"""
  461. spec = children[0]
  462. name = children[1].symbol
  463. size = children[2].value
  464. return _XdrFixedLengthArray(name, spec, size)
  465. def variable_length_array(self, children):
  466. """Instantiate one _XdrVariableLengthArray declaration object"""
  467. spec = children[0]
  468. name = children[1].symbol
  469. if children[2] is not None:
  470. maxsize = children[2].value
  471. else:
  472. maxsize = "0"
  473. return _XdrVariableLengthArray(name, spec, maxsize)
  474. def optional_data(self, children):
  475. """Instantiate one _XdrOptionalData declaration object"""
  476. spec = children[0]
  477. name = children[1].symbol
  478. return _XdrOptionalData(name, spec)
  479. def basic(self, children):
  480. """Instantiate one _XdrBasic object"""
  481. spec = children[0]
  482. name = children[1].symbol
  483. return _XdrBasic(name, spec)
  484. def void(self, children):
  485. """Instantiate one _XdrVoid declaration object"""
  486. return _XdrVoid()
  487. def struct(self, children):
  488. """Instantiate one _XdrStruct object"""
  489. name = children[0].symbol
  490. fields = children[1].children
  491. last_field = fields[-1]
  492. if (
  493. isinstance(last_field, _XdrOptionalData)
  494. and name == last_field.spec.type_name
  495. ):
  496. return _XdrPointer(name, fields)
  497. return _XdrStruct(name, fields)
  498. def typedef(self, children):
  499. """Instantiate one _XdrTypedef object"""
  500. new_type = children[0]
  501. return _XdrTypedef(new_type)
  502. def case_spec(self, children):
  503. """Instantiate one _XdrCaseSpec object"""
  504. values = []
  505. for item in children[0:-1]:
  506. values.append(item.value)
  507. arm = children[-1]
  508. return _XdrCaseSpec(values, arm)
  509. def default_spec(self, children):
  510. """Instantiate one _XdrDefaultSpec object"""
  511. arm = children[0]
  512. return _XdrDefaultSpec(arm)
  513. def union(self, children):
  514. """Instantiate one _XdrUnion object"""
  515. name = children[0].symbol
  516. body = children[1]
  517. discriminant = body.children[0].children[0]
  518. cases = body.children[1:-1]
  519. default = body.children[-1]
  520. return _XdrUnion(name, discriminant, cases, default)
  521. def procedure_def(self, children):
  522. """Instantiate one _RpcProcedure object"""
  523. result = children[0]
  524. name = children[1].symbol
  525. argument = children[2]
  526. number = children[3].value
  527. return _RpcProcedure(name, number, argument, result)
  528. def version_def(self, children):
  529. """Instantiate one _RpcVersion object"""
  530. name = children[0].symbol
  531. number = children[-1].value
  532. procedures = children[1:-1]
  533. return _RpcVersion(name, number, procedures)
  534. def program_def(self, children):
  535. """Instantiate one _RpcProgram object"""
  536. name = children[0].symbol
  537. number = children[-1].value
  538. versions = children[1:-1]
  539. return _RpcProgram(name, number, versions)
  540. def pragma_def(self, children):
  541. """Instantiate one _Pragma object"""
  542. directive = children[0].children[0].data
  543. match directive:
  544. case "big_endian_directive":
  545. big_endian.append(children[1].symbol)
  546. case "exclude_directive":
  547. excluded_apis.append(children[1].symbol)
  548. case "header_directive":
  549. global header_name
  550. header_name = children[1].symbol
  551. case "public_directive":
  552. public_apis.append(children[1].symbol)
  553. case _:
  554. raise NotImplementedError("Directive not supported")
  555. return _Pragma()
  556. def passthru_def(self, children):
  557. """Instantiate one _XdrPassthru object"""
  558. token = children[0]
  559. content = token.value[1:]
  560. return _XdrPassthru(content)
  561. transformer = ast_utils.create_transformer(this_module, ParseToAst())
  562. def _merge_consecutive_passthru(definitions: List[Definition]) -> List[Definition]:
  563. """Merge consecutive passthru definitions into single nodes"""
  564. result = []
  565. i = 0
  566. while i < len(definitions):
  567. if isinstance(definitions[i].value, _XdrPassthru):
  568. lines = [definitions[i].value.content]
  569. meta = definitions[i].meta
  570. j = i + 1
  571. while j < len(definitions) and isinstance(definitions[j].value, _XdrPassthru):
  572. lines.append(definitions[j].value.content)
  573. j += 1
  574. merged = _XdrPassthru("\n".join(lines))
  575. result.append(Definition(meta, merged))
  576. i = j
  577. else:
  578. result.append(definitions[i])
  579. i += 1
  580. return result
  581. def transform_parse_tree(parse_tree):
  582. """Transform productions into an abstract syntax tree"""
  583. ast = transformer.transform(parse_tree)
  584. ast.definitions = _merge_consecutive_passthru(ast.definitions)
  585. return ast
  586. def get_header_name() -> str:
  587. """Return header name set by pragma header directive"""
  588. return header_name