aas-core-codegen 0.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. aas_core_codegen/__init__.py +6 -0
  2. aas_core_codegen/__main__.py +8 -0
  3. aas_core_codegen/common.py +500 -0
  4. aas_core_codegen/cpp/__init__.py +1 -0
  5. aas_core_codegen/cpp/aas_common/__init__.py +6 -0
  6. aas_core_codegen/cpp/aas_common/_generate.py +713 -0
  7. aas_core_codegen/cpp/common.py +681 -0
  8. aas_core_codegen/cpp/constants/__init__.py +6 -0
  9. aas_core_codegen/cpp/constants/_generate.py +568 -0
  10. aas_core_codegen/cpp/description.py +654 -0
  11. aas_core_codegen/cpp/enhancing/__init__.py +4 -0
  12. aas_core_codegen/cpp/enhancing/_generate.py +993 -0
  13. aas_core_codegen/cpp/iteration/__init__.py +6 -0
  14. aas_core_codegen/cpp/iteration/_generate.py +2332 -0
  15. aas_core_codegen/cpp/jsonization/__init__.py +6 -0
  16. aas_core_codegen/cpp/jsonization/_generate.py +2619 -0
  17. aas_core_codegen/cpp/main.py +694 -0
  18. aas_core_codegen/cpp/naming.py +170 -0
  19. aas_core_codegen/cpp/optionaling.py +557 -0
  20. aas_core_codegen/cpp/pattern/__init__.py +6 -0
  21. aas_core_codegen/cpp/pattern/_generate.py +508 -0
  22. aas_core_codegen/cpp/revm/__init__.py +6 -0
  23. aas_core_codegen/cpp/revm/_generate.py +1149 -0
  24. aas_core_codegen/cpp/stringification/__init__.py +5 -0
  25. aas_core_codegen/cpp/stringification/_generate.py +955 -0
  26. aas_core_codegen/cpp/structure/__init__.py +7 -0
  27. aas_core_codegen/cpp/structure/_generate.py +1503 -0
  28. aas_core_codegen/cpp/transpilation.py +1383 -0
  29. aas_core_codegen/cpp/unrolling.py +159 -0
  30. aas_core_codegen/cpp/verification/__init__.py +6 -0
  31. aas_core_codegen/cpp/verification/_generate.py +3073 -0
  32. aas_core_codegen/cpp/visitation/__init__.py +6 -0
  33. aas_core_codegen/cpp/visitation/_generate.py +521 -0
  34. aas_core_codegen/cpp/wstringification/__init__.py +5 -0
  35. aas_core_codegen/cpp/wstringification/_generate.py +586 -0
  36. aas_core_codegen/cpp/xmlization/__init__.py +6 -0
  37. aas_core_codegen/cpp/xmlization/_generate.py +5373 -0
  38. aas_core_codegen/cpp/yielding.py +201 -0
  39. aas_core_codegen/csharp/__init__.py +1 -0
  40. aas_core_codegen/csharp/common.py +224 -0
  41. aas_core_codegen/csharp/constants/__init__.py +5 -0
  42. aas_core_codegen/csharp/constants/_generate.py +409 -0
  43. aas_core_codegen/csharp/copying/__init__.py +4 -0
  44. aas_core_codegen/csharp/copying/_generate.py +498 -0
  45. aas_core_codegen/csharp/description.py +1103 -0
  46. aas_core_codegen/csharp/enhancing/__init__.py +4 -0
  47. aas_core_codegen/csharp/enhancing/_generate.py +667 -0
  48. aas_core_codegen/csharp/jsonization/__init__.py +4 -0
  49. aas_core_codegen/csharp/jsonization/_generate.py +1630 -0
  50. aas_core_codegen/csharp/main.py +421 -0
  51. aas_core_codegen/csharp/naming.py +157 -0
  52. aas_core_codegen/csharp/reporting/__init__.py +4 -0
  53. aas_core_codegen/csharp/reporting/_generate.py +266 -0
  54. aas_core_codegen/csharp/stringification/__init__.py +4 -0
  55. aas_core_codegen/csharp/stringification/_generate.py +243 -0
  56. aas_core_codegen/csharp/structure/__init__.py +6 -0
  57. aas_core_codegen/csharp/structure/_generate.py +1341 -0
  58. aas_core_codegen/csharp/transpilation.py +990 -0
  59. aas_core_codegen/csharp/unrolling.py +211 -0
  60. aas_core_codegen/csharp/verification/__init__.py +6 -0
  61. aas_core_codegen/csharp/verification/_generate.py +1457 -0
  62. aas_core_codegen/csharp/visitation/__init__.py +5 -0
  63. aas_core_codegen/csharp/visitation/_generate.py +579 -0
  64. aas_core_codegen/csharp/xmlization/__init__.py +4 -0
  65. aas_core_codegen/csharp/xmlization/_generate.py +1980 -0
  66. aas_core_codegen/golang/__init__.py +1 -0
  67. aas_core_codegen/golang/aas_common/__init__.py +4 -0
  68. aas_core_codegen/golang/aas_common/_generate.py +152 -0
  69. aas_core_codegen/golang/common.py +303 -0
  70. aas_core_codegen/golang/constants/__init__.py +5 -0
  71. aas_core_codegen/golang/constants/_generate.py +339 -0
  72. aas_core_codegen/golang/description.py +501 -0
  73. aas_core_codegen/golang/enhancing/__init__.py +4 -0
  74. aas_core_codegen/golang/enhancing/_generate.py +527 -0
  75. aas_core_codegen/golang/jsonization/__init__.py +4 -0
  76. aas_core_codegen/golang/jsonization/_generate.py +1740 -0
  77. aas_core_codegen/golang/main.py +368 -0
  78. aas_core_codegen/golang/naming.py +412 -0
  79. aas_core_codegen/golang/pointering.py +631 -0
  80. aas_core_codegen/golang/reporting/__init__.py +4 -0
  81. aas_core_codegen/golang/reporting/_generate.py +218 -0
  82. aas_core_codegen/golang/stringification/__init__.py +4 -0
  83. aas_core_codegen/golang/stringification/_generate.py +394 -0
  84. aas_core_codegen/golang/structure/__init__.py +6 -0
  85. aas_core_codegen/golang/structure/_generate.py +1493 -0
  86. aas_core_codegen/golang/transpilation.py +1191 -0
  87. aas_core_codegen/golang/unrolling.py +159 -0
  88. aas_core_codegen/golang/verification/__init__.py +6 -0
  89. aas_core_codegen/golang/verification/_generate.py +1513 -0
  90. aas_core_codegen/golang/xmlization/__init__.py +4 -0
  91. aas_core_codegen/golang/xmlization/_generate.py +2507 -0
  92. aas_core_codegen/infer_for_schema/__init__.py +21 -0
  93. aas_core_codegen/infer_for_schema/_inline.py +693 -0
  94. aas_core_codegen/infer_for_schema/_len.py +527 -0
  95. aas_core_codegen/infer_for_schema/_pattern.py +311 -0
  96. aas_core_codegen/infer_for_schema/_set.py +394 -0
  97. aas_core_codegen/infer_for_schema/_stringify.py +201 -0
  98. aas_core_codegen/infer_for_schema/_types.py +135 -0
  99. aas_core_codegen/infer_for_schema/match.py +122 -0
  100. aas_core_codegen/intermediate/__init__.py +78 -0
  101. aas_core_codegen/intermediate/_hierarchy.py +397 -0
  102. aas_core_codegen/intermediate/_stringify.py +989 -0
  103. aas_core_codegen/intermediate/_translate.py +5128 -0
  104. aas_core_codegen/intermediate/_types.py +2901 -0
  105. aas_core_codegen/intermediate/construction.py +750 -0
  106. aas_core_codegen/intermediate/doc.py +344 -0
  107. aas_core_codegen/intermediate/pattern_verification.py +428 -0
  108. aas_core_codegen/intermediate/revm.py +985 -0
  109. aas_core_codegen/intermediate/type_inference.py +2266 -0
  110. aas_core_codegen/java/__init__.py +1 -0
  111. aas_core_codegen/java/common.py +197 -0
  112. aas_core_codegen/java/constants/__init__.py +5 -0
  113. aas_core_codegen/java/constants/_generate.py +334 -0
  114. aas_core_codegen/java/copying/__init__.py +4 -0
  115. aas_core_codegen/java/copying/_generate.py +502 -0
  116. aas_core_codegen/java/description.py +774 -0
  117. aas_core_codegen/java/enhancing/__init__.py +4 -0
  118. aas_core_codegen/java/enhancing/_generate.py +820 -0
  119. aas_core_codegen/java/generation/__init__.py +5 -0
  120. aas_core_codegen/java/generation/_generate.py +285 -0
  121. aas_core_codegen/java/jsonization/__init__.py +4 -0
  122. aas_core_codegen/java/jsonization/_generate.py +1472 -0
  123. aas_core_codegen/java/main.py +438 -0
  124. aas_core_codegen/java/naming.py +187 -0
  125. aas_core_codegen/java/optional.py +514 -0
  126. aas_core_codegen/java/reporting/__init__.py +4 -0
  127. aas_core_codegen/java/reporting/_generate.py +248 -0
  128. aas_core_codegen/java/stringification/__init__.py +4 -0
  129. aas_core_codegen/java/stringification/_generate.py +212 -0
  130. aas_core_codegen/java/structure/__init__.py +6 -0
  131. aas_core_codegen/java/structure/_generate.py +1767 -0
  132. aas_core_codegen/java/transpilation.py +1111 -0
  133. aas_core_codegen/java/verification/__init__.py +6 -0
  134. aas_core_codegen/java/verification/_generate.py +1536 -0
  135. aas_core_codegen/java/visitation/__init__.py +5 -0
  136. aas_core_codegen/java/visitation/_generate.py +689 -0
  137. aas_core_codegen/java/xmlization/__init__.py +4 -0
  138. aas_core_codegen/java/xmlization/_generate.py +2274 -0
  139. aas_core_codegen/jsonld/__init__.py +1 -0
  140. aas_core_codegen/jsonld/main.py +455 -0
  141. aas_core_codegen/jsonschema/__init__.py +1 -0
  142. aas_core_codegen/jsonschema/main.py +982 -0
  143. aas_core_codegen/main.py +245 -0
  144. aas_core_codegen/naming.py +133 -0
  145. aas_core_codegen/opcua/__init__.py +1 -0
  146. aas_core_codegen/opcua/main.py +1525 -0
  147. aas_core_codegen/opcua/naming.py +126 -0
  148. aas_core_codegen/parse/__init__.py +46 -0
  149. aas_core_codegen/parse/_rules.py +796 -0
  150. aas_core_codegen/parse/_stringify.py +532 -0
  151. aas_core_codegen/parse/_translate.py +3940 -0
  152. aas_core_codegen/parse/_types.py +973 -0
  153. aas_core_codegen/parse/retree/__init__.py +46 -0
  154. aas_core_codegen/parse/retree/_fix.py +434 -0
  155. aas_core_codegen/parse/retree/_parse.py +1143 -0
  156. aas_core_codegen/parse/retree/_render.py +298 -0
  157. aas_core_codegen/parse/retree/_stringify.py +199 -0
  158. aas_core_codegen/parse/retree/_types.py +362 -0
  159. aas_core_codegen/parse/retree/_visitor.py +70 -0
  160. aas_core_codegen/parse/tree.py +1303 -0
  161. aas_core_codegen/protobuf/__init__.py +1 -0
  162. aas_core_codegen/protobuf/common.py +225 -0
  163. aas_core_codegen/protobuf/description.py +1102 -0
  164. aas_core_codegen/protobuf/main.py +115 -0
  165. aas_core_codegen/protobuf/naming.py +143 -0
  166. aas_core_codegen/protobuf/structure/__init__.py +6 -0
  167. aas_core_codegen/protobuf/structure/_generate.py +502 -0
  168. aas_core_codegen/py.typed +1 -0
  169. aas_core_codegen/python/__init__.py +1 -0
  170. aas_core_codegen/python/aas_common/__init__.py +4 -0
  171. aas_core_codegen/python/aas_common/_generate.py +63 -0
  172. aas_core_codegen/python/common.py +406 -0
  173. aas_core_codegen/python/constants/__init__.py +5 -0
  174. aas_core_codegen/python/constants/_generate.py +377 -0
  175. aas_core_codegen/python/description.py +508 -0
  176. aas_core_codegen/python/jsonization/__init__.py +4 -0
  177. aas_core_codegen/python/jsonization/_generate.py +1391 -0
  178. aas_core_codegen/python/main.py +323 -0
  179. aas_core_codegen/python/naming.py +255 -0
  180. aas_core_codegen/python/stringification/__init__.py +4 -0
  181. aas_core_codegen/python/stringification/_generate.py +129 -0
  182. aas_core_codegen/python/structure/__init__.py +6 -0
  183. aas_core_codegen/python/structure/_generate.py +1801 -0
  184. aas_core_codegen/python/transpilation.py +958 -0
  185. aas_core_codegen/python/unrolling.py +156 -0
  186. aas_core_codegen/python/verification/__init__.py +6 -0
  187. aas_core_codegen/python/verification/_generate.py +1471 -0
  188. aas_core_codegen/python/xmlization/__init__.py +4 -0
  189. aas_core_codegen/python/xmlization/_generate.py +3003 -0
  190. aas_core_codegen/python_protobuf/__init__.py +1 -0
  191. aas_core_codegen/python_protobuf/main.py +1424 -0
  192. aas_core_codegen/python_protobuf/naming.py +85 -0
  193. aas_core_codegen/rdf_shacl/__init__.py +1 -0
  194. aas_core_codegen/rdf_shacl/_description.py +351 -0
  195. aas_core_codegen/rdf_shacl/common.py +206 -0
  196. aas_core_codegen/rdf_shacl/main.py +114 -0
  197. aas_core_codegen/rdf_shacl/naming.py +145 -0
  198. aas_core_codegen/rdf_shacl/rdf.py +435 -0
  199. aas_core_codegen/rdf_shacl/shacl.py +453 -0
  200. aas_core_codegen/run.py +124 -0
  201. aas_core_codegen/smoke/__init__.py +1 -0
  202. aas_core_codegen/smoke/main.py +219 -0
  203. aas_core_codegen/specific_implementations.py +72 -0
  204. aas_core_codegen/stringify.py +333 -0
  205. aas_core_codegen/typescript/__init__.py +1 -0
  206. aas_core_codegen/typescript/aas_common/__init__.py +4 -0
  207. aas_core_codegen/typescript/aas_common/_generate.py +472 -0
  208. aas_core_codegen/typescript/common.py +340 -0
  209. aas_core_codegen/typescript/constants/__init__.py +5 -0
  210. aas_core_codegen/typescript/constants/_generate.py +347 -0
  211. aas_core_codegen/typescript/description.py +530 -0
  212. aas_core_codegen/typescript/jsonization/__init__.py +4 -0
  213. aas_core_codegen/typescript/jsonization/_generate.py +1510 -0
  214. aas_core_codegen/typescript/main.py +258 -0
  215. aas_core_codegen/typescript/naming.py +189 -0
  216. aas_core_codegen/typescript/stringification/__init__.py +4 -0
  217. aas_core_codegen/typescript/stringification/_generate.py +367 -0
  218. aas_core_codegen/typescript/structure/__init__.py +6 -0
  219. aas_core_codegen/typescript/structure/_generate.py +2500 -0
  220. aas_core_codegen/typescript/transpilation.py +1051 -0
  221. aas_core_codegen/typescript/unrolling.py +159 -0
  222. aas_core_codegen/typescript/verification/__init__.py +6 -0
  223. aas_core_codegen/typescript/verification/_generate.py +1578 -0
  224. aas_core_codegen/xsd/__init__.py +1 -0
  225. aas_core_codegen/xsd/main.py +1187 -0
  226. aas_core_codegen/xsd/naming.py +83 -0
  227. aas_core_codegen/yielding/__init__.py +1 -0
  228. aas_core_codegen/yielding/flow.py +139 -0
  229. aas_core_codegen/yielding/linear.py +754 -0
  230. aas_core_codegen-0.0.16.dist-info/METADATA +211 -0
  231. aas_core_codegen-0.0.16.dist-info/RECORD +604 -0
  232. aas_core_codegen-0.0.16.dist-info/WHEEL +5 -0
  233. aas_core_codegen-0.0.16.dist-info/entry_points.txt +3 -0
  234. aas_core_codegen-0.0.16.dist-info/licenses/AUTHORS +9 -0
  235. aas_core_codegen-0.0.16.dist-info/licenses/LICENSE +23 -0
  236. aas_core_codegen-0.0.16.dist-info/top_level.txt +2 -0
  237. dev/continuous_integration/__init__.py +1 -0
  238. dev/continuous_integration/check_help_in_readme.py +208 -0
  239. dev/continuous_integration/check_init_and_pyproject_consistent.py +154 -0
  240. dev/continuous_integration/precommit.py +400 -0
  241. dev/dev_scripts/__init__.py +1 -0
  242. dev/dev_scripts/compare_rendered_regexes_against_source_py.py +42 -0
  243. dev/dev_scripts/copy_to_aas_core3_cpp.py +100 -0
  244. dev/dev_scripts/copy_to_aas_core3_java.py +90 -0
  245. dev/dev_scripts/download_latest_aas_core_meta_v3.py +114 -0
  246. dev/dev_scripts/draw_bipartite_graph_based_on_lines.py +37 -0
  247. dev/dev_scripts/run_tests_with_rerecord.py +69 -0
  248. dev/dev_scripts/update_to_aas_core_meta.py +174 -0
  249. dev/integration_tests/input/jsonschema/boilerplate/main.py +55 -0
  250. dev/integration_tests/input/meta_model.py +38 -0
  251. dev/integration_tests/input/python/boilerplate/main.py +153 -0
  252. dev/integration_tests/main.py +258 -0
  253. dev/test_data/csharp/test_structure/concrete_class_with_descendants/meta_model.py +15 -0
  254. dev/test_data/csharp/test_structure/constructor_without_arguments/all_properties_optional/meta_model.py +9 -0
  255. dev/test_data/csharp/test_structure/constructor_without_arguments/no_properties/meta_model.py +6 -0
  256. dev/test_data/csharp/test_verification/builtin_functions/len/on_list/meta_model.py +20 -0
  257. dev/test_data/csharp/test_verification/builtin_functions/len/on_str/meta_model.py +16 -0
  258. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_prefix/meta_model.py +8 -0
  259. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_suffix/meta_model.py +8 -0
  260. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_group_with_quantifier/meta_model.py +8 -0
  261. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_the_middle/meta_model.py +8 -0
  262. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_union/meta_model.py +8 -0
  263. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/single_utf32_literal/meta_model.py +8 -0
  264. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_within_group/meta_model.py +8 -0
  265. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_without_group/meta_model.py +8 -0
  266. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_beginning/meta_model.py +8 -0
  267. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_end/meta_model.py +8 -0
  268. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/in_the_middle/meta_model.py +8 -0
  269. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/multiple/meta_model.py +8 -0
  270. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single/meta_model.py +8 -0
  271. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single_with_quantifier/meta_model.py +8 -0
  272. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/mixed_with_non_utf32/meta_model.py +8 -0
  273. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/more_than_two_high_surrogates/meta_model.py +8 -0
  274. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges/meta_model.py +8 -0
  275. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges_mixed_with_non_utf32/meta_model.py +8 -0
  276. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate/meta_model.py +8 -0
  277. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate_with_quantifier/meta_model.py +8 -0
  278. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/two_high_surrogates/meta_model.py +8 -0
  279. dev/test_data/intermediate/expected/class/empty/meta_model.py +6 -0
  280. dev/test_data/intermediate/expected/class/implementation_specific_method/meta_model.py +8 -0
  281. dev/test_data/intermediate/expected/class/inheritance/meta_model.py +41 -0
  282. dev/test_data/intermediate/expected/class/methods_with_contracts/meta_model.py +15 -0
  283. dev/test_data/intermediate/expected/class/only_method_no_property/meta_model.py +7 -0
  284. dev/test_data/intermediate/expected/class/only_property_no_method/meta_model.py +9 -0
  285. dev/test_data/intermediate/expected/constant/constant_set/of_enum/meta_model.py +12 -0
  286. dev/test_data/intermediate/expected/constant/constant_set/of_str/meta_model.py +4 -0
  287. dev/test_data/intermediate/expected/constant/constant_set/with_description/meta_model.py +6 -0
  288. dev/test_data/intermediate/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
  289. dev/test_data/intermediate/expected/constant/constant_str/only_value/meta_model.py +7 -0
  290. dev/test_data/intermediate/expected/constant/constant_str/with_description/meta_model.py +5 -0
  291. dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_in_literal/meta_model.py +20 -0
  292. dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_outside_literal/meta_model.py +20 -0
  293. dev/test_data/intermediate/expected/empty/meta_model.py +2 -0
  294. dev/test_data/intermediate/expected/enumeration/meta_model.py +9 -0
  295. dev/test_data/intermediate/expected/interface/basic/meta_model.py +14 -0
  296. dev/test_data/intermediate/expected/interface/empty/meta_model.py +7 -0
  297. dev/test_data/intermediate/expected/interface/inheritance/meta_model.py +27 -0
  298. dev/test_data/intermediate/expected/interface/method_signature/meta_model.py +10 -0
  299. dev/test_data/intermediate/expected/interface/only_constructor/meta_model.py +11 -0
  300. dev/test_data/intermediate/expected/method/non_mutating/implementation_specific/meta_model.py +12 -0
  301. dev/test_data/intermediate/expected/method/non_mutating/understood/meta_model.py +11 -0
  302. dev/test_data/intermediate/expected/type_annotation/atomic/meta_model.py +9 -0
  303. dev/test_data/intermediate/expected/type_annotation/subscripted/class/meta_model.py +13 -0
  304. dev/test_data/intermediate/expected/type_annotation/subscripted/primitive/meta_model.py +9 -0
  305. dev/test_data/intermediate/unexpected/constant_set/of_enum/enumeration_literals_in_subset_outside_of_superset/meta_model.py +20 -0
  306. dev/test_data/intermediate/unexpected/constant_set/of_enum/invalid_literal/meta_model.py +11 -0
  307. dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_between_enumeration_and_literal/meta_model.py +30 -0
  308. dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_in_enumerations_between_subset_and_superset/meta_model.py +21 -0
  309. dev/test_data/intermediate/unexpected/constant_set/of_str/literals_in_subset_outside_of_superset/meta_model.py +18 -0
  310. dev/test_data/intermediate/unexpected/constant_set/of_str/mismatch_between_type_annotation_and_literals/meta_model.py +10 -0
  311. dev/test_data/intermediate/unexpected/constant_set/of_str/superset_and_subset_mismatch_in_type/meta_model.py +12 -0
  312. dev/test_data/intermediate/unexpected/constraints/dangling_constraintref/meta_model.py +18 -0
  313. dev/test_data/intermediate/unexpected/constraints/duplicate_constraints/meta_model.py +20 -0
  314. dev/test_data/intermediate/unexpected/documentation/unexpected_documentation_elements/meta_model.py +34 -0
  315. dev/test_data/intermediate/unexpected/invariant/class_invariant_uses_re/meta_model.py +10 -0
  316. dev/test_data/intermediate/unexpected/invariant/invariant_of_constrained_primitive_uses_re/meta_model.py +7 -0
  317. dev/test_data/intermediate/unexpected/invariant/unexpected_argument_count_to_len/meta_model.py +20 -0
  318. dev/test_data/intermediate/unexpected/invariant/unhandled_built_in_function/meta_model.py +16 -0
  319. dev/test_data/intermediate/unexpected/method_definitions/non_constant_default/meta_model.py +7 -0
  320. dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/default_non_none/meta_model.py +16 -0
  321. dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/no_default/meta_model.py +16 -0
  322. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/after_inheritance/meta_model.py +58 -0
  323. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/type_missmatch/meta_model.py +9 -0
  324. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/within_class/meta_model.py +22 -0
  325. dev/test_data/jsonschema/test_main/regression_when_len_constraints_on_inherited_property/meta_model.py +28 -0
  326. dev/test_data/opcua/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
  327. dev/test_data/opcua/test_main/classes_with_invariants/meta_model.py +21 -0
  328. dev/test_data/opcua/test_main/concrete_class_with_descendant/meta_model.py +27 -0
  329. dev/test_data/opcua/test_main/concrete_class_with_enum/meta_model.py +21 -0
  330. dev/test_data/opcua/test_main/concrete_class_with_list_of_instances/meta_model.py +21 -0
  331. dev/test_data/opcua/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  332. dev/test_data/opcua/test_main/concrete_class_with_string/meta_model.py +13 -0
  333. dev/test_data/opcua/test_main/constrained_primitive/meta_model.py +20 -0
  334. dev/test_data/opcua/test_main/multiple_inheritance/meta_model.py +25 -0
  335. dev/test_data/parse/expected/constant/constant_set/of_enum/meta_model.py +12 -0
  336. dev/test_data/parse/expected/constant/constant_set/of_str/meta_model.py +4 -0
  337. dev/test_data/parse/expected/constant/constant_set/with_description/meta_model.py +6 -0
  338. dev/test_data/parse/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
  339. dev/test_data/parse/expected/constant/constant_str/only_value/meta_model.py +7 -0
  340. dev/test_data/parse/expected/constant/constant_str/with_description/meta_model.py +5 -0
  341. dev/test_data/parse/expected/enum/ok/meta_model.py +15 -0
  342. dev/test_data/parse/expected/implementation_specific_class/properties_and_methods_in_implementation_specific_class/meta_model.py +17 -0
  343. dev/test_data/parse/expected/inheritance/basic/meta_model.py +11 -0
  344. dev/test_data/parse/expected/inheritance/diamond/meta_model.py +26 -0
  345. dev/test_data/parse/expected/inheritance/inheritance_from_concrete_class/meta_model.py +10 -0
  346. dev/test_data/parse/expected/invariants/in_relation/meta_model.py +16 -0
  347. dev/test_data/parse/expected/method/arguments/meta_model.py +7 -0
  348. dev/test_data/parse/expected/method/basic/meta_model.py +7 -0
  349. dev/test_data/parse/expected/method/contracts/condition_as_keyword_argument/meta_model.py +8 -0
  350. dev/test_data/parse/expected/method/contracts/condition_as_positional_argument/meta_model.py +8 -0
  351. dev/test_data/parse/expected/method/contracts/description_as_keyword_argument/meta_model.py +8 -0
  352. dev/test_data/parse/expected/method/contracts/description_as_positional_argument/meta_model.py +8 -0
  353. dev/test_data/parse/expected/method/contracts/multiple_contracts_in_order/meta_model.py +17 -0
  354. dev/test_data/parse/expected/method/contracts/postcondition/basic/meta_model.py +10 -0
  355. dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_keyword_arguments/meta_model.py +9 -0
  356. dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_positional_arguments/meta_model.py +9 -0
  357. dev/test_data/parse/expected/method/default/meta_model.py +9 -0
  358. dev/test_data/parse/expected/method/description/meta_model.py +8 -0
  359. dev/test_data/parse/expected/method/is_implementation_specific/meta_model.py +8 -0
  360. dev/test_data/parse/expected/method/non_mutating/meta_model.py +11 -0
  361. dev/test_data/parse/expected/method/returns_none/meta_model.py +7 -0
  362. dev/test_data/parse/expected/method/returns_something/meta_model.py +7 -0
  363. dev/test_data/parse/expected/single_class/description/meta_model.py +12 -0
  364. dev/test_data/parse/expected/single_class/empty/meta_model.py +6 -0
  365. dev/test_data/parse/expected/single_class/property/description/meta_model.py +14 -0
  366. dev/test_data/parse/expected/single_class/property/mandatory/meta_model.py +6 -0
  367. dev/test_data/parse/expected/single_class/property/optional/meta_model.py +6 -0
  368. dev/test_data/parse/expected/single_class/property/recursion_to_entity/meta_model.py +6 -0
  369. dev/test_data/parse/unexpected/class_decorators/non_name_decorator/meta_model.py +7 -0
  370. dev/test_data/parse/unexpected/class_decorators/unknown_decorator/meta_model.py +7 -0
  371. dev/test_data/parse/unexpected/class_definitions/is_abstract_and_implementation_specific/meta_model.py +8 -0
  372. dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_before_a_method/meta_model.py +11 -0
  373. dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_for_a_pass/meta_model.py +9 -0
  374. dev/test_data/parse/unexpected/class_definitions/unexpected_double_description_for_a_property/meta_model.py +10 -0
  375. dev/test_data/parse/unexpected/class_inheritances/inheriting_from_implementation_specific_parent/meta_model.py +20 -0
  376. dev/test_data/parse/unexpected/class_inheritances/non_name_super_class/meta_model.py +6 -0
  377. dev/test_data/parse/unexpected/enum/expression_as_assignment_value/meta_model.py +6 -0
  378. dev/test_data/parse/unexpected/enum/non_assignment/meta_model.py +8 -0
  379. dev/test_data/parse/unexpected/enum/non_string_literal/meta_model.py +6 -0
  380. dev/test_data/parse/unexpected/enum/unexpected_inheritance/meta_model.py +6 -0
  381. dev/test_data/parse/unexpected/method_contracts/contract/non_lambda_condition/meta_model.py +8 -0
  382. dev/test_data/parse/unexpected/method_contracts/contract/non_string_literal_description/meta_model.py +8 -0
  383. dev/test_data/parse/unexpected/method_contracts/contract/without_any_arguments/meta_model.py +8 -0
  384. dev/test_data/parse/unexpected/method_contracts/contract/without_condition/meta_model.py +8 -0
  385. dev/test_data/parse/unexpected/method_contracts/postcondition/OLD_in_postcondition_without_snapshot/meta_model.py +8 -0
  386. dev/test_data/parse/unexpected/method_contracts/postcondition/argument_missing_in_function/meta_model.py +8 -0
  387. dev/test_data/parse/unexpected/method_contracts/precondition/argument_missing_in_function/meta_model.py +8 -0
  388. dev/test_data/parse/unexpected/method_contracts/snapshot/argument_missing_in_function/meta_model.py +8 -0
  389. dev/test_data/parse/unexpected/method_contracts/snapshot/capture_not_a_lambda/meta_model.py +8 -0
  390. dev/test_data/parse/unexpected/method_contracts/snapshot/invalid_name/meta_model.py +8 -0
  391. dev/test_data/parse/unexpected/method_contracts/snapshot/name_not_a_string_literal/meta_model.py +8 -0
  392. dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_capture/meta_model.py +8 -0
  393. dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_name/meta_model.py +8 -0
  394. dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_constructor/meta_model.py +8 -0
  395. dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_verification_function/meta_model.py +8 -0
  396. dev/test_data/parse/unexpected/method_decorators/non_name_decorator/meta_model.py +8 -0
  397. dev/test_data/parse/unexpected/method_decorators/unknown_call_decorator/meta_model.py +8 -0
  398. dev/test_data/parse/unexpected/method_decorators/unknown_name_decorator/meta_model.py +8 -0
  399. dev/test_data/parse/unexpected/method_definitions/argument_with_final/meta_model.py +7 -0
  400. dev/test_data/parse/unexpected/method_definitions/argument_without_a_type_annotation/meta_model.py +7 -0
  401. dev/test_data/parse/unexpected/method_definitions/default_for_self/meta_model.py +7 -0
  402. dev/test_data/parse/unexpected/method_definitions/dunder/meta_model.py +7 -0
  403. dev/test_data/parse/unexpected/method_definitions/init_with_return_type/meta_model.py +7 -0
  404. dev/test_data/parse/unexpected/method_definitions/with_keyword_only_arguments/meta_model.py +7 -0
  405. dev/test_data/parse/unexpected/method_definitions/with_positional_arguments/meta_model.py +7 -0
  406. dev/test_data/parse/unexpected/method_definitions/with_type_annotation_for_self/meta_model.py +7 -0
  407. dev/test_data/parse/unexpected/method_definitions/with_variable_arguments/meta_model.py +7 -0
  408. dev/test_data/parse/unexpected/method_definitions/with_variable_keyword_arguments/meta_model.py +7 -0
  409. dev/test_data/parse/unexpected/method_definitions/without_arguments/meta_model.py +7 -0
  410. dev/test_data/parse/unexpected/method_definitions/without_self/meta_model.py +7 -0
  411. dev/test_data/parse/unexpected/method_definitions/without_type_annotation_for_result/meta_model.py +7 -0
  412. dev/test_data/parse/unexpected/property_definitions/final_without_subscript/meta_model.py +6 -0
  413. dev/test_data/parse/unexpected/property_definitions/nested_final/meta_model.py +6 -0
  414. dev/test_data/parse/unexpected/property_definitions/non_simple/meta_model.py +6 -0
  415. dev/test_data/parse/unexpected/property_definitions/unexpected_assignment/meta_model.py +6 -0
  416. dev/test_data/parse/unexpected/property_definitions/unexpected_non_name_property/meta_model.py +6 -0
  417. dev/test_data/parse/unexpected/property_definitions/without_type_annotation/meta_model.py +6 -0
  418. dev/test_data/parse/unexpected/symbol_table/constant_set_with_a_non_set_subset/meta_model.py +6 -0
  419. dev/test_data/parse/unexpected/symbol_table/dangling_inheritance/meta_model.py +6 -0
  420. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_a_property/meta_model.py +6 -0
  421. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_an_argument/meta_model.py +7 -0
  422. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_constant_set/meta_model.py +6 -0
  423. dev/test_data/parse/unexpected/symbol_table/dangling_subset_in_constant_set/meta_model.py +4 -0
  424. dev/test_data/parse/unexpected/symbol_table/inheritance_from_non_class/meta_model.py +10 -0
  425. dev/test_data/parse_retree/expected/character_set/common_escaping/source.py +1 -0
  426. dev/test_data/parse_retree/expected/character_set/complementing/double_caret/source.py +1 -0
  427. dev/test_data/parse_retree/expected/character_set/complementing/multiple_ranges/source.py +1 -0
  428. dev/test_data/parse_retree/expected/character_set/complementing/suffix_dash/source.py +1 -0
  429. dev/test_data/parse_retree/expected/character_set/escape_first_caret/source.py +1 -0
  430. dev/test_data/parse_retree/expected/character_set/literals_which_need_no_escaping_in_characters_set_but_need_escaping_outside/source.py +1 -0
  431. dev/test_data/parse_retree/expected/character_set/multiple_ranges/source.py +1 -0
  432. dev/test_data/parse_retree/expected/character_set/single_literal/source.py +1 -0
  433. dev/test_data/parse_retree/expected/character_set/single_range/source.py +1 -0
  434. dev/test_data/parse_retree/expected/character_set/unescaped_dash/only_dash/source.py +1 -0
  435. dev/test_data/parse_retree/expected/character_set/unescaped_dash/prefix_dash/source.py +1 -0
  436. dev/test_data/parse_retree/expected/character_set/unescaped_dash/suffix_dash/source.py +1 -0
  437. dev/test_data/parse_retree/expected/dot/source.py +1 -0
  438. dev/test_data/parse_retree/expected/empty/group/source.py +1 -0
  439. dev/test_data/parse_retree/expected/empty/group_in_a_group/source.py +1 -0
  440. dev/test_data/parse_retree/expected/empty/group_of_union_of_empty_concatenations/source.py +1 -0
  441. dev/test_data/parse_retree/expected/empty/regex/source.py +1 -0
  442. dev/test_data/parse_retree/expected/empty/union_of_empty_concatenations/source.py +1 -0
  443. dev/test_data/parse_retree/expected/escaped_literals/source.py +1 -0
  444. dev/test_data/parse_retree/expected/formatted_value/at_the_beginning/source.py +1 -0
  445. dev/test_data/parse_retree/expected/formatted_value/at_the_end/source.py +1 -0
  446. dev/test_data/parse_retree/expected/formatted_value/in_the_middle/source.py +1 -0
  447. dev/test_data/parse_retree/expected/formatted_value/single_formatted_value/source.py +1 -0
  448. dev/test_data/parse_retree/expected/literal/source.py +1 -0
  449. dev/test_data/parse_retree/expected/quantifier/greedy/at_least_3/source.py +1 -0
  450. dev/test_data/parse_retree/expected/quantifier/greedy/at_least_one/source.py +1 -0
  451. dev/test_data/parse_retree/expected/quantifier/greedy/at_most_3/source.py +1 -0
  452. dev/test_data/parse_retree/expected/quantifier/greedy/exactly_3/source.py +1 -0
  453. dev/test_data/parse_retree/expected/quantifier/greedy/maybe/source.py +1 -0
  454. dev/test_data/parse_retree/expected/quantifier/greedy/zero_or_more/source.py +1 -0
  455. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_3/source.py +1 -0
  456. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_one/source.py +1 -0
  457. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_most_3/source.py +1 -0
  458. dev/test_data/parse_retree/expected/quantifier/non_greedy/exactly_3/source.py +1 -0
  459. dev/test_data/parse_retree/expected/quantifier/non_greedy/maybe/source.py +1 -0
  460. dev/test_data/parse_retree/expected/quantifier/non_greedy/zero_or_more/source.py +1 -0
  461. dev/test_data/parse_retree/expected/quantifier/on_a_character_set/source.py +1 -0
  462. dev/test_data/parse_retree/expected/quantifier/on_a_formatted_value/source.py +1 -0
  463. dev/test_data/parse_retree/expected/quantifier/on_a_group/source.py +1 -0
  464. dev/test_data/parse_retree/expected/quantifier/on_a_literal/source.py +1 -0
  465. dev/test_data/parse_retree/expected/start_and_stop_symbols/double_end_symbol/source.py +1 -0
  466. dev/test_data/parse_retree/expected/start_and_stop_symbols/double_start_symbol/source.py +1 -0
  467. dev/test_data/parse_retree/expected/start_and_stop_symbols/end_symbol_in_the_middle/source.py +1 -0
  468. dev/test_data/parse_retree/expected/start_and_stop_symbols/only_start_symbol/source.py +1 -0
  469. dev/test_data/parse_retree/expected/start_and_stop_symbols/only_stop_symbol/source.py +1 -0
  470. dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_at_the_beginning/source.py +1 -0
  471. dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_in_the_middle/source.py +1 -0
  472. dev/test_data/parse_retree/expected/start_and_stop_symbols/stop_symbol_at_the_end/source.py +1 -0
  473. dev/test_data/parse_retree/expected/union/of_character_sets/source.py +1 -0
  474. dev/test_data/parse_retree/expected/union/of_groups/source.py +1 -0
  475. dev/test_data/parse_retree/expected/union/of_string_literals/source.py +1 -0
  476. dev/test_data/parse_retree/expected/union/within_group/source.py +1 -0
  477. dev/test_data/parse_retree/expected/whitespace/source.py +1 -0
  478. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/Uxxxxxxxx_out_of_range/source.py +1 -0
  479. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/only_backslash/source.py +1 -0
  480. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_Uxxxxxxxx/source.py +1 -0
  481. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_uxxxx/source.py +1 -0
  482. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_x/source.py +1 -0
  483. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unexpected_escaping/source.py +1 -0
  484. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/digit/source.py +1 -0
  485. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_digit/source.py +1 -0
  486. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_whitespace/source.py +1 -0
  487. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_word/source.py +1 -0
  488. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/whitespace/source.py +1 -0
  489. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/word/source.py +1 -0
  490. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/Uxxxxxxxx_out_of_range/source.py +1 -0
  491. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/only_backslash/source.py +1 -0
  492. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_Uxxxxxxxx/source.py +1 -0
  493. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_uxxxx/source.py +1 -0
  494. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_x/source.py +1 -0
  495. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unexpected_escaping/source.py +1 -0
  496. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/digit/source.py +1 -0
  497. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_digit/source.py +1 -0
  498. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_whitespace/source.py +1 -0
  499. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_word/source.py +1 -0
  500. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/whitespace/source.py +1 -0
  501. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/word/source.py +1 -0
  502. dev/test_data/parse_retree/unexpected/invalid_character_range/source.py +1 -0
  503. dev/test_data/parse_retree/unexpected/invalid_quantifier/at_least_x/source.py +1 -0
  504. dev/test_data/parse_retree/unexpected/invalid_quantifier/between_3_and_x/source.py +1 -0
  505. dev/test_data/parse_retree/unexpected/invalid_quantifier/exactly_x/source.py +1 -0
  506. dev/test_data/parse_retree/unexpected/unhandled_group_directives/source.py +1 -0
  507. dev/test_data/parse_retree/unexpected/unterminated/character_set/source.py +1 -0
  508. dev/test_data/parse_retree/unexpected/unterminated/group/source.py +1 -0
  509. dev/test_data/parse_retree/unexpected/unterminated/group_of_union_of_empty_concatenations/source.py +1 -0
  510. dev/test_data/parse_retree/unexpected/unterminated/quantifier/source.py +1 -0
  511. dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_comma/source.py +1 -0
  512. dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_number_and_comma/source.py +1 -0
  513. dev/test_data/proto/test_main/expected/abstract_and_concrete_classes/meta_model.py +37 -0
  514. dev/test_data/proto/test_main/expected/concrete_class_with_descendants/meta_model.py +30 -0
  515. dev/test_data/proto/test_main/expected/concrete_class_with_enum/meta_model.py +21 -0
  516. dev/test_data/proto/test_main/expected/concrete_class_with_list_of_instances/meta_model.py +21 -0
  517. dev/test_data/proto/test_main/expected/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  518. dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/expected_output/pbization.py +532 -0
  519. dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
  520. dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/expected_output/pbization.py +527 -0
  521. dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/meta_model.py +27 -0
  522. dev/test_data/python_protobuf/test_main/concrete_class_with_enum/expected_output/pbization.py +290 -0
  523. dev/test_data/python_protobuf/test_main/concrete_class_with_enum/meta_model.py +21 -0
  524. dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/expected_output/pbization.py +328 -0
  525. dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/meta_model.py +23 -0
  526. dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/expected_output/pbization.py +274 -0
  527. dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  528. dev/test_data/rdf_shacl/test_main/expected/regression_when_lang_string_class_is_missing/meta_model.py +29 -0
  529. dev/test_data/rdf_shacl/test_main/expected/regression_when_len_constraints_on_inherited_property/meta_model.py +27 -0
  530. dev/test_data/rdf_shacl/test_main/unexpected/regression_len_constraint_on_class_property/meta_model.py +61 -0
  531. dev/test_data/real_meta_models/aas_core_meta.v3.py +5721 -0
  532. dev/test_data/smoke/test_main/unexpected/infer_for_schema_error/meta_model.py +12 -0
  533. dev/test_data/smoke/test_main/unexpected/intermediate_error/meta_model.py +18 -0
  534. dev/test_data/smoke/test_main/unexpected/parse_error/meta_model.py +5 -0
  535. dev/test_data/smoke/test_main/unexpected/pattern_verification_unparsable_regex/direct_match/meta_model.py +8 -0
  536. dev/test_data/smoke/test_main/unexpected/type_error/meta_model.py +18 -0
  537. dev/tests/__init__.py +1 -0
  538. dev/tests/common.py +197 -0
  539. dev/tests/cpp/__init__.py +0 -0
  540. dev/tests/cpp/test_common.py +32 -0
  541. dev/tests/cpp/test_main.py +144 -0
  542. dev/tests/cpp/test_pattern.py +188 -0
  543. dev/tests/cpp/test_verification.py +189 -0
  544. dev/tests/cpp/test_yielding.py +225 -0
  545. dev/tests/csharp/__init__.py +0 -0
  546. dev/tests/csharp/live_test_main.py +109 -0
  547. dev/tests/csharp/test_common.py +28 -0
  548. dev/tests/csharp/test_description.py +684 -0
  549. dev/tests/csharp/test_main.py +129 -0
  550. dev/tests/csharp/test_structure.py +93 -0
  551. dev/tests/csharp/test_verification.py +82 -0
  552. dev/tests/description.py +29 -0
  553. dev/tests/golang/__init__.py +0 -0
  554. dev/tests/golang/test_common.py +78 -0
  555. dev/tests/golang/test_main.py +128 -0
  556. dev/tests/infer_for_schema/__init__.py +0 -0
  557. dev/tests/infer_for_schema/common.py +47 -0
  558. dev/tests/infer_for_schema/test_len_on_properties.py +955 -0
  559. dev/tests/infer_for_schema/test_len_on_self.py +580 -0
  560. dev/tests/infer_for_schema/test_patterns_on_properties.py +686 -0
  561. dev/tests/infer_for_schema/test_patterns_on_self.py +258 -0
  562. dev/tests/infer_for_schema/test_property_in_set_of_enumeration_literals.py +600 -0
  563. dev/tests/infer_for_schema/test_property_in_set_of_primitives.py +549 -0
  564. dev/tests/intermediate/__init__.py +0 -0
  565. dev/tests/intermediate/test_constructor.py +719 -0
  566. dev/tests/intermediate/test_hierarchy.py +221 -0
  567. dev/tests/intermediate/test_revm.py +134 -0
  568. dev/tests/intermediate/test_translate.py +337 -0
  569. dev/tests/intermediate/test_type_inference.py +333 -0
  570. dev/tests/intermediate/test_types.py +169 -0
  571. dev/tests/java/__init__.py +0 -0
  572. dev/tests/java/test_common.py +20 -0
  573. dev/tests/java/test_description.py +128 -0
  574. dev/tests/java/test_main.py +234 -0
  575. dev/tests/jsonld_context/test_main.py +79 -0
  576. dev/tests/opcua/__init__.py +3 -0
  577. dev/tests/opcua/test_main.py +110 -0
  578. dev/tests/our_jsonschema/__init__.py +3 -0
  579. dev/tests/our_jsonschema/test_main.py +232 -0
  580. dev/tests/parse/__init__.py +0 -0
  581. dev/tests/parse/test_parse.py +503 -0
  582. dev/tests/parse/test_retree.py +272 -0
  583. dev/tests/proto/__init__.py +0 -0
  584. dev/tests/proto/test_main.py +112 -0
  585. dev/tests/python/__init__.py +0 -0
  586. dev/tests/python/test_common.py +124 -0
  587. dev/tests/python/test_main.py +126 -0
  588. dev/tests/python/test_xml_playground.py +254 -0
  589. dev/tests/python_protobuf/__init__.py +0 -0
  590. dev/tests/python_protobuf/test_main.py +111 -0
  591. dev/tests/rdf_shacl/__init__.py +0 -0
  592. dev/tests/rdf_shacl/test_common.py +32 -0
  593. dev/tests/rdf_shacl/test_description.py +223 -0
  594. dev/tests/rdf_shacl/test_main.py +194 -0
  595. dev/tests/smoke/__init__.py +0 -0
  596. dev/tests/smoke/test_main.py +83 -0
  597. dev/tests/test_common.py +94 -0
  598. dev/tests/typescript/__init__.py +0 -0
  599. dev/tests/typescript/test_common.py +108 -0
  600. dev/tests/typescript/test_main.py +125 -0
  601. dev/tests/xsd/__init__.py +0 -0
  602. dev/tests/xsd/test_main.py +227 -0
  603. dev/tests/yielding/__init__.py +0 -0
  604. dev/tests/yielding/test_linear.py +558 -0
@@ -0,0 +1,985 @@
1
+ """
2
+ Transpile the regular expressions to instructions of a Virtual Machine.
3
+
4
+ The implementation in the standard library has exponential time complexity, so it was
5
+ a major blocker for most of the practical inputs. For example, see this bug report:
6
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93502
7
+
8
+ The virtual machine is based on Ken Thompson's approach published in:
9
+ Thompson, K., "Regular expression search algorithm", ACM 11(6) (June 1968)
10
+
11
+ We followed a very clear and concise blog post which described it in detail:
12
+ https://swtch.com/~rsc/regexp/regexp2.html
13
+
14
+ The ideas for additional instructions were taken from:
15
+ https://www.codeproject.com/Articles/5256833/Regex-as-a-Tiny-Threaded-Virtual-Machine
16
+ """
17
+ import dataclasses
18
+ import io
19
+ from typing import (
20
+ Final,
21
+ cast,
22
+ List,
23
+ Optional,
24
+ Union,
25
+ Tuple,
26
+ TextIO,
27
+ MutableMapping,
28
+ Sequence,
29
+ )
30
+
31
+ from icontract import require
32
+
33
+ from aas_core_codegen.common import assert_never, pairwise
34
+ from aas_core_codegen.parse import retree as parse_retree, tree as parse_tree
35
+
36
+
37
+ class Character(str):
38
+ """Represent a single character."""
39
+
40
+ @require(lambda text: len(text) == 1)
41
+ def __new__(cls, text: str) -> "Character":
42
+ return cast(Character, text)
43
+
44
+
45
+ @dataclasses.dataclass
46
+ class InstructionChar:
47
+ """Match a single character."""
48
+
49
+ character: Character
50
+
51
+
52
+ class Range:
53
+ """Define a character range."""
54
+
55
+ first: Final[Character]
56
+ last: Final[Character]
57
+
58
+ # fmt: off
59
+ @require(
60
+ lambda first, last: ord(first) <= ord(last),
61
+ "Range boundaries must be sorted."
62
+ )
63
+ # fmt: on
64
+ def __init__(self, first: Character, last: Character) -> None:
65
+ """Initialize with the given values."""
66
+ self.first = first
67
+ self.last = last
68
+
69
+ def __str__(self) -> str:
70
+ return f"{self.__class__.__name__}({self.first!r}, {self.last!r})"
71
+
72
+
73
+ def check_ranges_sorted_and_non_overlapping(ranges: Sequence[Range]) -> Optional[str]:
74
+ """
75
+ Check that the ranges' boundaries are sorted and non-overlapping.
76
+
77
+ If there are no errors, return ``None``. Otherwise, return a message explaining
78
+ what precisely was not satisfied.
79
+ """
80
+ for this_range, next_range in pairwise(ranges):
81
+ if ord(this_range.first) >= ord(next_range.last):
82
+ return (
83
+ f"The range {this_range} and its next range {next_range} "
84
+ f"are not in sorted order."
85
+ )
86
+
87
+ if ord(this_range.last) >= ord(next_range.first):
88
+ return f"The range {this_range} and its next range {next_range} overlap."
89
+
90
+ return None
91
+
92
+
93
+ class InstructionSet:
94
+ """Match a set of characters."""
95
+
96
+ ranges: Final[Sequence[Range]]
97
+
98
+ @require(lambda ranges: check_ranges_sorted_and_non_overlapping(ranges) is None)
99
+ def __init__(self, ranges: Sequence[Range]) -> None:
100
+ """Initialize with the given values."""
101
+ self.ranges = ranges
102
+
103
+ def __str__(self) -> str:
104
+ return f"{self.__class__.__name__}({self.ranges!r})"
105
+
106
+
107
+ class InstructionNotSet:
108
+ """Match an out-of-set character."""
109
+
110
+ ranges: Final[Sequence[Range]]
111
+
112
+ @require(lambda ranges: check_ranges_sorted_and_non_overlapping(ranges) is None)
113
+ def __init__(self, ranges: Sequence[Range]) -> None:
114
+ """Initialize with the given values."""
115
+ self.ranges = ranges
116
+
117
+ def __str__(self) -> str:
118
+ return f"{self.__class__.__name__}({self.ranges!r})"
119
+
120
+
121
+ @dataclasses.dataclass
122
+ class InstructionAny:
123
+ """Match any character."""
124
+
125
+
126
+ @dataclasses.dataclass
127
+ class InstructionMatch:
128
+ """Stop the thread and signal that we found a match."""
129
+
130
+
131
+ @dataclasses.dataclass
132
+ class InstructionJump:
133
+ """Jump to the indicated position in the program."""
134
+
135
+ target: int
136
+
137
+
138
+ @dataclasses.dataclass
139
+ class InstructionSplit:
140
+ """Split the program in two threads, both jumping to different locations."""
141
+
142
+ first_target: int
143
+ second_target: int
144
+
145
+
146
+ @dataclasses.dataclass
147
+ class InstructionEnd:
148
+ """Match the end-of-input."""
149
+
150
+
151
+ @dataclasses.dataclass
152
+ class _InstructionNoop:
153
+ """
154
+ Represent a no-operation instruction which does nothing.
155
+
156
+ This is used only as a place-holder during the translation.
157
+ """
158
+
159
+
160
+ Instruction = Union[
161
+ InstructionChar,
162
+ InstructionSet,
163
+ InstructionNotSet,
164
+ InstructionAny,
165
+ InstructionMatch,
166
+ InstructionJump,
167
+ InstructionSplit,
168
+ InstructionEnd,
169
+ ]
170
+
171
+
172
+ # NOTE (mristin):
173
+ # The classes ``_Leaf`` and ``_Node`` correspond to the translation phase, while
174
+ # the classes ``Leaf`` and ``Node`` are used to represent the final result.
175
+
176
+
177
+ @dataclasses.dataclass
178
+ class _Leaf:
179
+ """Represent a leaf node in the nested instruction tree during compilation."""
180
+
181
+ instruction: Union[Instruction, _InstructionNoop]
182
+ label: Optional[int] = None
183
+
184
+
185
+ @dataclasses.dataclass
186
+ class _Node:
187
+ """Represent nested instructions during compilation."""
188
+
189
+ re_node: parse_retree.Node
190
+ children: List["_NodeOrLeaf"]
191
+
192
+
193
+ _NodeOrLeaf = Union[_Node, _Leaf]
194
+
195
+
196
+ @dataclasses.dataclass
197
+ class Leaf:
198
+ """Represent a leaf node in the nested instruction tree."""
199
+
200
+ instruction: Instruction
201
+ label: Optional[int] = None
202
+
203
+
204
+ @dataclasses.dataclass
205
+ class Node:
206
+ """Represent nested instructions related to a part of the regular expression."""
207
+
208
+ re_node: parse_retree.Node
209
+ children: List["NodeOrLeaf"]
210
+
211
+
212
+ NodeOrLeaf = Union[Node, Leaf]
213
+
214
+
215
+ class _CheckForFormattedValue(parse_retree.PassThroughVisitor):
216
+ """Check that no ``FormattedValue`` is contained in a pattern."""
217
+
218
+ def __init__(self) -> None:
219
+ self.has_formatted_value = False
220
+
221
+ def visit_term(self, node: parse_retree.Term) -> None:
222
+ if isinstance(node.value, parse_tree.FormattedValue):
223
+ self.has_formatted_value = True
224
+
225
+ super().visit_term(node)
226
+
227
+
228
+ class _CheckForNonGreedyQuantifiers(parse_retree.PassThroughVisitor):
229
+ """Check for presence of non-greedy quantifiers in a pattern."""
230
+
231
+ def __init__(self) -> None:
232
+ self.has_non_greedy_quantifiers = False
233
+
234
+ def visit_quantifier(self, node: parse_retree.Quantifier) -> None:
235
+ if node.non_greedy:
236
+ self.has_non_greedy_quantifiers = True
237
+
238
+ super().visit_quantifier(node)
239
+
240
+
241
+ class _RegexRenderer(parse_retree.Renderer):
242
+ """
243
+ Render regex patterns for readable comments.
244
+
245
+ In contrast to :py:class:`parse_retree.Renderer`, we also render
246
+ the :py:class:`parse_retree.Char` as we need to cover the granularity of a single
247
+ character in this module.
248
+ """
249
+
250
+ def transform_char(
251
+ self, node: parse_retree.Char
252
+ ) -> List[Union[str, parse_tree.FormattedValue]]:
253
+ return self.char_to_str_and_escape_or_encode_if_necessary(
254
+ node=node, escaping=parse_retree.Renderer._ESCAPING_IN_CHARACTER_LITERALS
255
+ )
256
+
257
+
258
+ _REGEX_RENDERER = _RegexRenderer()
259
+
260
+
261
+ def _render_re_node(re_node: parse_retree.Node) -> str:
262
+ """Render the pattern as a string for comments."""
263
+ parts = _REGEX_RENDERER.transform(re_node)
264
+ assert all(
265
+ isinstance(part, str) for part in parts
266
+ ), f"Expected all rendered parts to be strings, but got: {parts}"
267
+
268
+ return "".join(parts) # type: ignore
269
+
270
+
271
+ class _Translator(parse_retree.Transformer[_Node]):
272
+ """Translate the regular expression to nested instructions."""
273
+
274
+ def __init__(self) -> None:
275
+ self._next_label = 0
276
+
277
+ def _obtain_label(self) -> int:
278
+ """
279
+ Return the current next label, and increment it for the next call.
280
+
281
+ Do not fiddle with :py:attr:`_next_label` yourself; use this function.
282
+ """
283
+ result = self._next_label
284
+ self._next_label += 1
285
+ return result
286
+
287
+ def transform_union_expr(self, node: parse_retree.UnionExpr) -> _Node:
288
+ if len(node.uniates) == 0:
289
+ return _Node(re_node=node, children=[_Leaf(instruction=_InstructionNoop())])
290
+ elif len(node.uniates) == 1:
291
+ return self.transform(node.uniates[0])
292
+ else:
293
+ pass
294
+
295
+ children = [] # type: List[_NodeOrLeaf]
296
+
297
+ final_label = self._obtain_label()
298
+
299
+ for i, uniate in enumerate(node.uniates):
300
+ if i < len(node.uniates) - 1:
301
+ l0 = self._obtain_label()
302
+ l1 = self._obtain_label()
303
+
304
+ children.append(
305
+ _Leaf(InstructionSplit(first_target=l0, second_target=l1))
306
+ )
307
+
308
+ children.append(_Leaf(_InstructionNoop(), label=l0))
309
+
310
+ children.append(self.transform(uniate))
311
+
312
+ children.append(_Leaf(InstructionJump(target=final_label)))
313
+
314
+ children.append(_Leaf(_InstructionNoop(), label=l1))
315
+ else:
316
+ children.append(self.transform(uniate))
317
+
318
+ children.append(_Leaf(_InstructionNoop(), label=final_label))
319
+
320
+ return _Node(re_node=node, children=children)
321
+
322
+ def transform_concatenation(self, node: parse_retree.Concatenation) -> _Node:
323
+ if len(node.concatenants) == 0:
324
+ return _Node(re_node=node, children=[_Leaf(instruction=_InstructionNoop())])
325
+
326
+ elif len(node.concatenants) == 1:
327
+ return self.transform(node=node.concatenants[0])
328
+
329
+ else:
330
+ return _Node(
331
+ re_node=node,
332
+ children=[
333
+ self.transform(concatenant) for concatenant in node.concatenants
334
+ ],
335
+ )
336
+
337
+ def transform_symbol(self, node: parse_retree.Symbol) -> _Node:
338
+ if node.kind is parse_retree.SymbolKind.START:
339
+ raise AssertionError(
340
+ "We expect that the caller skipped the start anchor "
341
+ "as we always expect the patterns to be anchored at start, and there "
342
+ "is no matching to be done against the start anchor. We decided "
343
+ "against introduction of a no-op instruction since that only eats up "
344
+ "resources, which we can avoid with a bit of smartness in "
345
+ "the transpilation phase."
346
+ )
347
+
348
+ elif node.kind is parse_retree.SymbolKind.END:
349
+ return _Node(re_node=node, children=[_Leaf(instruction=InstructionEnd())])
350
+
351
+ elif node.kind is parse_retree.SymbolKind.DOT:
352
+ return _Node(
353
+ re_node=node,
354
+ children=[_Leaf(instruction=InstructionAny())],
355
+ )
356
+
357
+ else:
358
+ assert_never(node.kind)
359
+
360
+ def transform_term(self, node: parse_retree.Term) -> _Node:
361
+ assert not isinstance(node.value, parse_tree.FormattedValue), (
362
+ "Unexpected formatted value in the regular expression to be "
363
+ "transformed into a program for Regex Virtual Machine. "
364
+ "This should have been checked before. "
365
+ f"The formatted value is: {parse_tree.dump(node.value)}"
366
+ )
367
+
368
+ if node.quantifier is not None:
369
+ if node.quantifier.non_greedy:
370
+ raise AssertionError(
371
+ "(mristin, 2024-06-04) Only non-greedy quantifiers are currently "
372
+ "translated to a program for a RegEx virtual machine. We did not "
373
+ "cover non-greedy quantifiers for simplicity, as we currently have "
374
+ "no meta-model where they are required. The presence of non-greedy "
375
+ "quantifiers should have been caught before, as we explicitly "
376
+ "check for them when transpiling a meta-model. Please report "
377
+ "this exception to the developers as a bug."
378
+ )
379
+
380
+ if node.quantifier.minimum == 1 and node.quantifier.maximum == 1:
381
+ return self.transform(node.value)
382
+
383
+ children = [] # type: List[_NodeOrLeaf]
384
+
385
+ if node.quantifier.maximum is not None:
386
+ for _ in range(0, node.quantifier.minimum):
387
+ children.append(self.transform(node.value))
388
+
389
+ optional_count = node.quantifier.maximum - node.quantifier.minimum
390
+ if optional_count > 0:
391
+ final_label = self._obtain_label()
392
+
393
+ for _ in range(optional_count):
394
+ l1 = self._obtain_label()
395
+ children.append(
396
+ _Leaf(
397
+ InstructionSplit(
398
+ first_target=l1, second_target=final_label
399
+ )
400
+ )
401
+ )
402
+ children.append(_Leaf(_InstructionNoop(), label=l1))
403
+ children.append(self.transform(node.value))
404
+
405
+ children.append(_Leaf(_InstructionNoop(), label=final_label))
406
+ else:
407
+ if node.quantifier.minimum == 0:
408
+ l1 = self._obtain_label()
409
+ l2 = self._obtain_label()
410
+ final_label = self._obtain_label()
411
+
412
+ children.append(
413
+ _Leaf(
414
+ InstructionSplit(
415
+ first_target=l2, second_target=final_label
416
+ ),
417
+ label=l1,
418
+ )
419
+ )
420
+
421
+ children.append(_Leaf(_InstructionNoop(), label=l2))
422
+ children.append(self.transform(node.value))
423
+ children.append(_Leaf(InstructionJump(target=l1)))
424
+
425
+ children.append(_Leaf(_InstructionNoop(), label=final_label))
426
+
427
+ else:
428
+ # NOTE (mristin):
429
+ # The last mandatory repetition will be used for the unbounded loop.
430
+ for _ in range(0, node.quantifier.minimum - 1):
431
+ children.append(self.transform(node.value))
432
+
433
+ l1 = self._obtain_label()
434
+ final_label = self._obtain_label()
435
+
436
+ children.append(_Leaf(_InstructionNoop(), label=l1))
437
+ children.append(self.transform(node.value))
438
+ children.append(
439
+ _Leaf(
440
+ InstructionSplit(first_target=l1, second_target=final_label)
441
+ )
442
+ )
443
+ children.append(_Leaf(_InstructionNoop(), label=final_label))
444
+
445
+ return _Node(re_node=node, children=children)
446
+
447
+ else:
448
+ return self.transform(node.value)
449
+
450
+ def transform_group(self, node: parse_retree.Group) -> _Node:
451
+ return self.transform(node.union)
452
+
453
+ def transform_char(self, node: parse_retree.Char) -> _Node:
454
+ return _Node(
455
+ re_node=node,
456
+ children=[
457
+ _Leaf(instruction=InstructionChar(character=Character(node.character)))
458
+ ],
459
+ )
460
+
461
+ def transform_quantifier(self, node: parse_retree.Quantifier) -> _Node:
462
+ raise AssertionError(
463
+ f"Expected the quantifier to be already handled "
464
+ f"in {_Translator.transform_term.__name__}. We should have never gotten "
465
+ f"here."
466
+ )
467
+
468
+ def transform_char_set(self, node: parse_retree.CharSet) -> _Node:
469
+ ranges = [
470
+ Range(
471
+ first=Character(re_range.start.character),
472
+ last=(
473
+ Character(re_range.end.character)
474
+ if re_range.end is not None
475
+ else Character(re_range.start.character)
476
+ ),
477
+ )
478
+ for re_range in node.ranges
479
+ ]
480
+
481
+ ranges.sort(key=lambda rng: rng.first)
482
+
483
+ if node.complementing:
484
+ return _Node(
485
+ re_node=node,
486
+ children=[_Leaf(instruction=InstructionNotSet(ranges=ranges))],
487
+ )
488
+ else:
489
+ return _Node(
490
+ re_node=node,
491
+ children=[_Leaf(instruction=InstructionSet(ranges=ranges))],
492
+ )
493
+
494
+ def transform_range(self, node: parse_retree.Range) -> _Node:
495
+ raise AssertionError(
496
+ "Expected to handle a regex range within the character set"
497
+ )
498
+
499
+ def transform_regex(self, node: parse_retree.Regex) -> _Node:
500
+ non_anchored_exception_message = (
501
+ "(mristin, 2024-05-31): We expect all the patterns which need "
502
+ "to be transpiled to instructions of the RegEx virtual machine "
503
+ "to be anchored at the start (``^``) and at the end (``$``). Please "
504
+ "consider re-writing your pattern with putting a prefix ``^.*`` if you "
505
+ "want to match an arbitrary prefix, and a suffix ``.*$`` if you want to "
506
+ "match an arbitrary suffix. "
507
+ "If you really need this feature, please contact the developers. "
508
+ f"The regular expression was: {_render_re_node(node)}"
509
+ )
510
+
511
+ if len(node.union.uniates) == 0 or len(node.union.uniates[0].concatenants) == 0:
512
+ raise NotImplementedError(non_anchored_exception_message)
513
+
514
+ first_term = node.union.uniates[0].concatenants[0]
515
+ last_term = node.union.uniates[0].concatenants[-1]
516
+
517
+ first_symbol_is_start = isinstance(first_term.value, parse_retree.Symbol) and (
518
+ first_term.value.kind is parse_retree.SymbolKind.START
519
+ )
520
+ last_symbol_is_end = isinstance(last_term.value, parse_retree.Symbol) and (
521
+ last_term.value.kind is parse_retree.SymbolKind.END
522
+ )
523
+
524
+ if (
525
+ len(node.union.uniates) != 1
526
+ or not first_symbol_is_start
527
+ or not last_symbol_is_end
528
+ ):
529
+ parts = [non_anchored_exception_message]
530
+ if len(node.union.uniates) > 1:
531
+ parts.append(
532
+ "Expected no alternation in the root group of "
533
+ "the pattern (only concatenation), but the pattern starts "
534
+ "with an alternation. You can not properly anchor "
535
+ "with an alternation."
536
+ )
537
+
538
+ if not first_symbol_is_start:
539
+ parts.append(
540
+ f"Expected the first term of the pattern to be a start anchor, "
541
+ f"but it is not. Got: {_render_re_node(first_term)}"
542
+ )
543
+
544
+ if not last_symbol_is_end:
545
+ parts.append(
546
+ f"Expected the last term of the pattern to be an end anchor, "
547
+ f"but it is not. Got: {_render_re_node(last_term)}"
548
+ )
549
+
550
+ raise NotImplementedError("\n\n".join(parts))
551
+
552
+ check_for_formatted_value = _CheckForFormattedValue()
553
+ check_for_formatted_value.visit(node)
554
+ if check_for_formatted_value.has_formatted_value:
555
+ raise AssertionError(
556
+ f"The regex you want to transpile to the instructions of "
557
+ f"a RegEx virtual machine contains a formatted value. "
558
+ f"The formatted values can only be transpiled into code, "
559
+ f"but can not be transpiled into instructions. "
560
+ f"Please check your code logic. "
561
+ f"The pattern was: {parse_retree.dump(node)}"
562
+ )
563
+
564
+ check_for_non_greedy_quantifiers = _CheckForNonGreedyQuantifiers()
565
+ check_for_non_greedy_quantifiers.visit(node)
566
+ if check_for_non_greedy_quantifiers.has_non_greedy_quantifiers:
567
+ raise NotImplementedError(
568
+ "(mristin, 2024-05-31): We did not implement the transpilation of "
569
+ "non-greedy quantifiers to instructions of a RegEx virtual machine "
570
+ "as this is more complex than the transpilation of the greedy ones. "
571
+ "If you need this feature, please contact the developers."
572
+ )
573
+
574
+ assert len(node.union.uniates) == 1, (
575
+ "Only concatenation expected at the root level since we must anchor "
576
+ "at the start and at the end."
577
+ )
578
+
579
+ # region Optimize for arbitrary suffix
580
+
581
+ # NOTE (mristin):
582
+ # We optimize here for the pattern ``.*$`` as we can put an instruction ``Match``
583
+ # just before the arbitrary suffix, and need not the match ``Any`` followed by
584
+ # the ``End``.
585
+ penultimate_term = (
586
+ node.union.uniates[0].concatenants[-2]
587
+ if len(node.union.uniates[0].concatenants) >= 2
588
+ else None
589
+ )
590
+
591
+ assert (
592
+ node.union.uniates[0].concatenants[0] is first_term
593
+ and isinstance(first_term.value, parse_retree.Symbol)
594
+ and first_term.value.kind is parse_retree.SymbolKind.START
595
+ ), "Expected the first term to be an anchor at ``^``"
596
+
597
+ assert (
598
+ last_term is node.union.uniates[0].concatenants[-1]
599
+ and isinstance(last_term.value, parse_retree.Symbol)
600
+ and (last_term.value.kind is parse_retree.SymbolKind.END)
601
+ ), "Expected the last term to be an anchor at ``$``"
602
+
603
+ if (
604
+ penultimate_term is not None
605
+ and isinstance(penultimate_term.value, parse_retree.Symbol)
606
+ and penultimate_term.value.kind is parse_retree.SymbolKind.DOT
607
+ and penultimate_term.quantifier is not None
608
+ and penultimate_term.quantifier.minimum == 0
609
+ and penultimate_term.quantifier.maximum is None
610
+ ):
611
+ # NOTE (mristin):
612
+ # We skip the start anchor as it is not transpiled to an instruction.
613
+ concatenants = node.union.uniates[0].concatenants[1:-2]
614
+ else:
615
+ # NOTE (mristin):
616
+ # We skip the start anchor as it is not transpiled to an instruction.
617
+ concatenants = node.union.uniates[0].concatenants[1:]
618
+
619
+ # endregion
620
+
621
+ children = [] # type: List[_NodeOrLeaf]
622
+ for concatenant in concatenants:
623
+ child = self.transform(concatenant)
624
+ children.append(child)
625
+
626
+ children.append(_Leaf(instruction=InstructionMatch()))
627
+
628
+ return _Node(
629
+ re_node=node,
630
+ children=children,
631
+ )
632
+
633
+
634
+ def _recursively_convert_node_for_public(raw_node_or_leaf: _NodeOrLeaf) -> NodeOrLeaf:
635
+ """
636
+ Convert the post-processed "raw" node into a node for the public use.
637
+
638
+ .. note::
639
+
640
+ All post-processing needs to be performed *before* calling this function.
641
+ This function only copy-converts the nodes into structures to be further
642
+ used by the downstream clients. No post-processing is performed here.
643
+ """
644
+ if isinstance(raw_node_or_leaf, _Leaf):
645
+ assert not isinstance(
646
+ raw_node_or_leaf.instruction, _InstructionNoop
647
+ ), "No no-op instructions expected in public"
648
+
649
+ return Leaf(
650
+ instruction=raw_node_or_leaf.instruction, label=raw_node_or_leaf.label
651
+ )
652
+
653
+ elif isinstance(raw_node_or_leaf, _Node):
654
+ children = [] # type: List[NodeOrLeaf]
655
+ for raw_child in raw_node_or_leaf.children:
656
+ children.append(_recursively_convert_node_for_public(raw_child))
657
+
658
+ return Node(re_node=raw_node_or_leaf.re_node, children=children)
659
+
660
+ else:
661
+ assert_never(raw_node_or_leaf)
662
+
663
+
664
+ def _linearize(node: _Node) -> List[_Leaf]:
665
+ """Make recursively a linear list over all the leaves."""
666
+ lst = [] # type: List[_Leaf]
667
+ for child in node.children:
668
+ if isinstance(child, _Leaf):
669
+ lst.append(child)
670
+ elif isinstance(child, _Node):
671
+ lst.extend(_linearize(child))
672
+ else:
673
+ assert_never(child)
674
+
675
+ return lst
676
+
677
+
678
+ def _relabel_in_place(root: _Node) -> None:
679
+ """
680
+ Re-assign labels according to the indices in a linearized sequence of instructions.
681
+
682
+ We expect that the no-op instructions will be removed, so they are not assigned
683
+ an index.
684
+ """
685
+ linearized_leaves = _linearize(root)
686
+
687
+ # NOTE (mristin):
688
+ # We index all the leaves except for no-op instructions which are going to be
689
+ # eventually removed. The indices thus correspond to the instructions *after*
690
+ # the no-op instructions are removed.
691
+
692
+ next_index = 0
693
+
694
+ # NOTE (mristin):
695
+ # We map on the ``id(leaf)`` as the leaves are not hashable.
696
+ leaf_to_index = dict() # type: MutableMapping[int, int]
697
+
698
+ for leaf in linearized_leaves:
699
+ if isinstance(leaf.instruction, _InstructionNoop):
700
+ continue
701
+
702
+ leaf_to_index[id(leaf)] = next_index
703
+ next_index += 1
704
+
705
+ # NOTE (mristin):
706
+ # This variable captures the mapping:
707
+ # arbitrary labelling 🠒 labeling according to indices.
708
+ #
709
+ # Only the leaves indicated by new labels will finally have a label at the end.
710
+ old_to_new_label = dict() # type: MutableMapping[int, int]
711
+
712
+ # NOTE (mristin):
713
+ # We iterate in reverse over the leaves so that a single non-no-op instruction
714
+ # can accumulate multiple labels for itself.
715
+
716
+ leaf_after_noop = None # type: Optional[_Leaf]
717
+ for leaf in reversed(linearized_leaves):
718
+ if isinstance(leaf.instruction, _InstructionNoop):
719
+ if leaf.label is not None:
720
+ assert leaf_after_noop is not None, (
721
+ "Expected at least one leaf *after* the no-op instruction. "
722
+ "Since the very last instruction must be a ``match`` instruction, "
723
+ "this must hold, so something obviously went wrong."
724
+ )
725
+
726
+ old_to_new_label[leaf.label] = leaf_to_index[id(leaf_after_noop)]
727
+ else:
728
+ if leaf.label is not None:
729
+ old_to_new_label[leaf.label] = leaf_to_index[id(leaf)]
730
+
731
+ leaf_after_noop = leaf
732
+
733
+ new_label_set = set(old_to_new_label.values())
734
+
735
+ for leaf in linearized_leaves:
736
+ if isinstance(leaf.instruction, _InstructionNoop):
737
+ leaf.label = None
738
+ continue
739
+
740
+ leaf_index = leaf_to_index[id(leaf)]
741
+
742
+ if leaf_index in new_label_set:
743
+ leaf.label = leaf_index
744
+ else:
745
+ leaf.label = None
746
+
747
+ if isinstance(leaf.instruction, InstructionJump):
748
+ leaf.instruction.target = old_to_new_label[leaf.instruction.target]
749
+
750
+ elif isinstance(leaf.instruction, InstructionSplit):
751
+ leaf.instruction.first_target = old_to_new_label[
752
+ leaf.instruction.first_target
753
+ ]
754
+
755
+ leaf.instruction.second_target = old_to_new_label[
756
+ leaf.instruction.second_target
757
+ ]
758
+ else:
759
+ # NOTE (mristin):
760
+ # Other instruction need not be adapted to the new labels.
761
+ pass
762
+
763
+
764
+ def _remove_noop_in_place(node: _Node) -> None:
765
+ """
766
+ Remove recursively all no-op instructions in place.
767
+
768
+ The no-op instructions are expected to have no labels attached to them.
769
+ """
770
+ new_children = [] # type: List[_NodeOrLeaf]
771
+ for child in node.children:
772
+ if isinstance(child, _Leaf):
773
+ if isinstance(child.instruction, _InstructionNoop):
774
+ assert child.label is None, (
775
+ f"Expected all no-op leaves to have their labels removed "
776
+ f"before calling {_remove_noop_in_place.__name__}"
777
+ )
778
+ continue
779
+
780
+ elif isinstance(child, _Node):
781
+ _remove_noop_in_place(child)
782
+
783
+ else:
784
+ assert_never(child)
785
+
786
+ new_children.append(child)
787
+
788
+ node.children = new_children
789
+
790
+
791
+ def translate(regex: parse_retree.Regex) -> Node:
792
+ """Translate the regular expression into a program."""
793
+ # NOTE (mristin):
794
+ # We call the nodes "raw" here which still need to be post-processed.
795
+ # The post-processing includes removal of no-ops, re-wiring of the labels *etc.*
796
+
797
+ translator = _Translator()
798
+ raw_root = translator.transform(regex)
799
+
800
+ _relabel_in_place(raw_root)
801
+ _remove_noop_in_place(raw_root)
802
+
803
+ root = _recursively_convert_node_for_public(raw_node_or_leaf=raw_root)
804
+ assert isinstance(root, Node), (
805
+ f"Only node and no leaf expected at the root of the regular expression, "
806
+ f"but got as root: {root}"
807
+ )
808
+
809
+ return root
810
+
811
+
812
+ def _determine_min_and_max_label(node_or_leaf: NodeOrLeaf) -> Optional[Tuple[int, int]]:
813
+ """
814
+ Iterate recursively over the nodes, and determine the extreme labels in the program.
815
+
816
+ If no node contains a label, return ``None``.
817
+ """
818
+ if isinstance(node_or_leaf, Leaf):
819
+ if node_or_leaf.label is not None:
820
+ return node_or_leaf.label, node_or_leaf.label
821
+ else:
822
+ return None
823
+
824
+ elif isinstance(node_or_leaf, Node):
825
+ minimum = None # type: Optional[int]
826
+ maximum = None # type: Optional[int]
827
+
828
+ for child in node_or_leaf.children:
829
+ maybe_child_min_max = _determine_min_and_max_label(node_or_leaf=child)
830
+ if maybe_child_min_max is not None:
831
+ child_min, child_max = maybe_child_min_max
832
+
833
+ if minimum is not None:
834
+ minimum = min(minimum, child_min)
835
+ else:
836
+ minimum = child_min
837
+
838
+ if maximum is not None:
839
+ maximum = max(maximum, child_max)
840
+ else:
841
+ maximum = child_max
842
+
843
+ assert (minimum is not None and maximum is not None) or (
844
+ minimum is None and maximum is None
845
+ ), (
846
+ f"Both minimum and maximum must be set or neither, "
847
+ f"but got: {minimum=}, {maximum=}"
848
+ )
849
+
850
+ if minimum is not None:
851
+ assert maximum is not None
852
+ return minimum, maximum
853
+ else:
854
+ assert maximum is None
855
+ return None
856
+ else:
857
+ assert_never(node_or_leaf)
858
+
859
+
860
+ @require(lambda indention: indention >= 0)
861
+ @require(lambda label_columns: label_columns >= 0)
862
+ def _write_recursively(
863
+ node_or_leaf: NodeOrLeaf, indention: int, label_columns: int, writer: TextIO
864
+ ) -> None:
865
+ """Write recursively the node or leaf as a human-readable text to the ``writer``."""
866
+ whitespace = " " * indention
867
+
868
+ if isinstance(node_or_leaf, Leaf):
869
+ if label_columns == 0:
870
+ label_prefix = ""
871
+ else:
872
+ if node_or_leaf.label is None:
873
+ label_prefix = " " * (label_columns + 2)
874
+ else:
875
+ # noinspection PyStringFormat
876
+ label_prefix = f"{{:0{label_columns}d}}: ".format(node_or_leaf.label)
877
+
878
+ instruction_str: str
879
+
880
+ if isinstance(node_or_leaf.instruction, InstructionChar):
881
+ instruction_str = f"char {node_or_leaf.instruction.character!r}"
882
+
883
+ elif isinstance(node_or_leaf.instruction, (InstructionSet, InstructionNotSet)):
884
+ ranges_str = "".join(
885
+ f"{rng.first}" if rng.first == rng.last else f"{rng.first}-{rng.last}"
886
+ for rng in node_or_leaf.instruction.ranges
887
+ )
888
+
889
+ if isinstance(node_or_leaf.instruction, InstructionSet):
890
+ instruction_str = f"set {ranges_str!r}"
891
+ elif isinstance(node_or_leaf.instruction, InstructionNotSet):
892
+ instruction_str = f"not-set {ranges_str!r}"
893
+ else:
894
+ assert_never(node_or_leaf.instruction)
895
+
896
+ elif isinstance(node_or_leaf.instruction, InstructionAny):
897
+ instruction_str = "any"
898
+
899
+ elif isinstance(node_or_leaf.instruction, InstructionMatch):
900
+ instruction_str = "match"
901
+
902
+ elif isinstance(node_or_leaf.instruction, InstructionJump):
903
+ instruction_str = f"jump {node_or_leaf.instruction.target}"
904
+
905
+ elif isinstance(node_or_leaf.instruction, InstructionSplit):
906
+ instruction_str = (
907
+ f"split {node_or_leaf.instruction.first_target}, "
908
+ f"{node_or_leaf.instruction.second_target}"
909
+ )
910
+
911
+ elif isinstance(node_or_leaf.instruction, InstructionEnd):
912
+ instruction_str = "end"
913
+
914
+ else:
915
+ assert_never(node_or_leaf.instruction)
916
+
917
+ writer.write(f"{label_prefix}{whitespace}{instruction_str}")
918
+
919
+ elif isinstance(node_or_leaf, Node):
920
+ if label_columns == 0:
921
+ label_prefix = ""
922
+ else:
923
+ label_prefix = " " * (label_columns + 2)
924
+
925
+ re_node_str = _render_re_node(node_or_leaf.re_node)
926
+ if len(node_or_leaf.children) == 0:
927
+ more_whitespace = " " * (indention + 1)
928
+ writer.write(
929
+ f"{label_prefix}{whitespace}# {re_node_str}\n"
930
+ f"{label_prefix}{whitespace}{{\n"
931
+ f"{label_prefix}{more_whitespace}# Nothing\n"
932
+ f"{label_prefix}{whitespace}}}"
933
+ )
934
+ elif len(node_or_leaf.children) == 1 and isinstance(
935
+ node_or_leaf.children[0], Leaf
936
+ ):
937
+ if not isinstance(
938
+ node_or_leaf.children[0].instruction,
939
+ (InstructionSet, InstructionNotSet, InstructionAny, InstructionChar),
940
+ ):
941
+ writer.write(f"{label_prefix}{whitespace}# {re_node_str}\n")
942
+
943
+ _write_recursively(
944
+ node_or_leaf=node_or_leaf.children[0],
945
+ indention=indention,
946
+ label_columns=label_columns,
947
+ writer=writer,
948
+ )
949
+ else:
950
+ writer.write(
951
+ f"{label_prefix}{whitespace}# {re_node_str}\n"
952
+ f"{label_prefix}{whitespace}{{\n"
953
+ )
954
+ for child in node_or_leaf.children:
955
+ _write_recursively(
956
+ node_or_leaf=child,
957
+ indention=indention + 1,
958
+ label_columns=label_columns,
959
+ writer=writer,
960
+ )
961
+
962
+ writer.write("\n")
963
+
964
+ writer.write(f"{label_prefix}{whitespace}}}")
965
+
966
+ else:
967
+ assert_never(node_or_leaf)
968
+
969
+
970
+ def dump(program: NodeOrLeaf) -> str:
971
+ """Write out the program as a readable nested list of instructions."""
972
+ maybe_min_max_label = _determine_min_and_max_label(node_or_leaf=program)
973
+
974
+ if maybe_min_max_label is None:
975
+ label_columns = 0
976
+ else:
977
+ min_label, max_label = maybe_min_max_label
978
+ label_columns = max(len(str(min_label)), len(str(max_label)))
979
+
980
+ writer = io.StringIO()
981
+ _write_recursively(
982
+ node_or_leaf=program, indention=0, label_columns=label_columns, writer=writer
983
+ )
984
+
985
+ return writer.getvalue()