synthra 0.1.0

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 (302) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +40 -0
  4. data/.yardopts +18 -0
  5. data/ACCESS_DOCS.md +116 -0
  6. data/ADVANCED_FEATURES_SUMMARY.md +245 -0
  7. data/CHANGELOG.md +498 -0
  8. data/CODE_OF_CONDUCT.md +122 -0
  9. data/CONTRIBUTING.md +307 -0
  10. data/DOCUMENTATION.md +204 -0
  11. data/DOCUMENTATION_GUIDE.md +194 -0
  12. data/LICENSE +22 -0
  13. data/README.md +1458 -0
  14. data/Rakefile +128 -0
  15. data/benchmark/README.md +591 -0
  16. data/benchmark/batch_generation.rb +63 -0
  17. data/benchmark/engine_comparison.rb +295 -0
  18. data/benchmark/single_record.rb +108 -0
  19. data/benchmark/streaming.rb +74 -0
  20. data/docs/ACTIVERECORD_INFERENCE.md +524 -0
  21. data/docs/API_SERVER.md +278 -0
  22. data/docs/CONFIG_FILE.md +315 -0
  23. data/docs/DATA_CONTRACTS.md +312 -0
  24. data/docs/ENHANCED_REPL.md +304 -0
  25. data/docs/FACTORY_BOT.md +271 -0
  26. data/docs/GITHUB_ACTION.md +420 -0
  27. data/docs/GRAPHQL_EXPORT.md +303 -0
  28. data/docs/GRAPHQL_FEDERATION.md +651 -0
  29. data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
  30. data/docs/LSP.md +189 -0
  31. data/docs/MIGRATION_GENERATOR.md +547 -0
  32. data/docs/MOCK_SERVER.md +280 -0
  33. data/docs/NATIVE_ENGINE.md +298 -0
  34. data/docs/OPENAPI_EXPORT.md +252 -0
  35. data/docs/PERFORMANCE_MODE.md +228 -0
  36. data/docs/PERSONAS.md +547 -0
  37. data/docs/PROPERTY_TESTING.md +284 -0
  38. data/docs/PROTOBUF_EXPORT.md +276 -0
  39. data/docs/QUALITY_METRICS.md +555 -0
  40. data/docs/QUICK_REFERENCE.md +88 -0
  41. data/docs/RAILS_ENGINE.md +404 -0
  42. data/docs/RAILS_INTEGRATION.md +454 -0
  43. data/docs/README.md +175 -0
  44. data/docs/REPL_QUICK_REFERENCE.md +149 -0
  45. data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
  46. data/docs/SCENARIOS.md +576 -0
  47. data/docs/SECURITY_TESTING.md +318 -0
  48. data/docs/SNAPSHOT_TESTING.md +308 -0
  49. data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
  50. data/docs/TERRAFORM_EXPORT.md +447 -0
  51. data/docs/TIME_TRAVEL.md +507 -0
  52. data/docs/USAGE_GUIDE.md +980 -0
  53. data/docs/WEBHOOK_SIMULATOR.md +579 -0
  54. data/docs/advanced_features.md +183 -0
  55. data/docs/api_reference.md +153 -0
  56. data/docs/behaviors.md +138 -0
  57. data/docs/best_practices.md +191 -0
  58. data/docs/dsl_reference.md +172 -0
  59. data/docs/examples.md +162 -0
  60. data/docs/generation_modes.md +125 -0
  61. data/docs/getting_started.md +92 -0
  62. data/docs/index.html +177 -0
  63. data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
  64. data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
  65. data/docs/troubleshooting.md +215 -0
  66. data/docs/type_reference.md +224 -0
  67. data/examples/hostile_mode_demo.rb +64 -0
  68. data/exe/synthra +6 -0
  69. data/ext/synthra_native/Cargo.lock +972 -0
  70. data/ext/synthra_native/Cargo.toml +46 -0
  71. data/ext/synthra_native/extconf.rb +41 -0
  72. data/ext/synthra_native/src/generator.rs +397 -0
  73. data/ext/synthra_native/src/lib.rs +229 -0
  74. data/ext/synthra_native/src/types.rs +1485 -0
  75. data/lib/generators/synthra/install_generator.rb +86 -0
  76. data/lib/generators/synthra/templates/api_response.dsl +15 -0
  77. data/lib/generators/synthra/templates/fake_data.rake +116 -0
  78. data/lib/generators/synthra/templates/synthra.yml +31 -0
  79. data/lib/generators/synthra/templates/synthra_support.rb +19 -0
  80. data/lib/generators/synthra/templates/user.dsl +11 -0
  81. data/lib/synthra/activerecord_inference.rb +394 -0
  82. data/lib/synthra/api.rb +381 -0
  83. data/lib/synthra/api_server.rb +718 -0
  84. data/lib/synthra/behaviors/applicator.rb +165 -0
  85. data/lib/synthra/behaviors/base.rb +155 -0
  86. data/lib/synthra/behaviors/close_connection.rb +60 -0
  87. data/lib/synthra/behaviors/deprecated.rb +100 -0
  88. data/lib/synthra/behaviors/failure.rb +69 -0
  89. data/lib/synthra/behaviors/latency.rb +103 -0
  90. data/lib/synthra/behaviors/partial_data.rb +83 -0
  91. data/lib/synthra/behaviors/randomize_order.rb +74 -0
  92. data/lib/synthra/behaviors/registry.rb +238 -0
  93. data/lib/synthra/behaviors/simulate_error.rb +79 -0
  94. data/lib/synthra/cli/commands/base.rb +105 -0
  95. data/lib/synthra/cli/commands/diff.rb +227 -0
  96. data/lib/synthra/cli/commands/docs.rb +67 -0
  97. data/lib/synthra/cli/commands/export.rb +150 -0
  98. data/lib/synthra/cli/commands/generate.rb +72 -0
  99. data/lib/synthra/cli/commands/import.rb +80 -0
  100. data/lib/synthra/cli/commands/lint.rb +53 -0
  101. data/lib/synthra/cli/commands/live.rb +57 -0
  102. data/lib/synthra/cli/commands/seed.rb +99 -0
  103. data/lib/synthra/cli/commands/validate.rb +28 -0
  104. data/lib/synthra/cli.rb +2471 -0
  105. data/lib/synthra/config_file.rb +129 -0
  106. data/lib/synthra/configuration.rb +281 -0
  107. data/lib/synthra/contracts_registry.rb +408 -0
  108. data/lib/synthra/database_seeder.rb +268 -0
  109. data/lib/synthra/deterministic_ids.rb +218 -0
  110. data/lib/synthra/documentation_generator.rb +414 -0
  111. data/lib/synthra/engine.rb +251 -0
  112. data/lib/synthra/errors.rb +1169 -0
  113. data/lib/synthra/export/base.rb +85 -0
  114. data/lib/synthra/export/csv.rb +101 -0
  115. data/lib/synthra/export/graphql.rb +266 -0
  116. data/lib/synthra/export/graphql_federation.rb +377 -0
  117. data/lib/synthra/export/graphviz.rb +258 -0
  118. data/lib/synthra/export/javascript.rb +327 -0
  119. data/lib/synthra/export/json_data.rb +61 -0
  120. data/lib/synthra/export/json_schema.rb +290 -0
  121. data/lib/synthra/export/openapi.rb +514 -0
  122. data/lib/synthra/export/protobuf.rb +483 -0
  123. data/lib/synthra/export/python.rb +560 -0
  124. data/lib/synthra/export/sql.rb +381 -0
  125. data/lib/synthra/export/sql_insert.rb +152 -0
  126. data/lib/synthra/export/terraform.rb +501 -0
  127. data/lib/synthra/export/type_mapping.rb +389 -0
  128. data/lib/synthra/export/typescript.rb +300 -0
  129. data/lib/synthra/export/xml_data.rb +104 -0
  130. data/lib/synthra/export/yaml_data.rb +56 -0
  131. data/lib/synthra/export.rb +404 -0
  132. data/lib/synthra/factory_bot_integration.rb +157 -0
  133. data/lib/synthra/field.rb +440 -0
  134. data/lib/synthra/functions/registry.rb +104 -0
  135. data/lib/synthra/generator/context.rb +372 -0
  136. data/lib/synthra/generator/engine.rb +336 -0
  137. data/lib/synthra/generator/faker_adapter.rb +425 -0
  138. data/lib/synthra/generator/modes.rb +444 -0
  139. data/lib/synthra/generator/resolver.rb +256 -0
  140. data/lib/synthra/generator/rng.rb +273 -0
  141. data/lib/synthra/generator/streamer.rb +63 -0
  142. data/lib/synthra/generator/uniqueness.rb +118 -0
  143. data/lib/synthra/initializer.rb +97 -0
  144. data/lib/synthra/limits.rb +279 -0
  145. data/lib/synthra/live_preview.rb +518 -0
  146. data/lib/synthra/loader_config.rb +78 -0
  147. data/lib/synthra/lsp/server.rb +689 -0
  148. data/lib/synthra/migration_generator.rb +301 -0
  149. data/lib/synthra/mixin.rb +174 -0
  150. data/lib/synthra/mock_server.rb +458 -0
  151. data/lib/synthra/native_engine.rb +304 -0
  152. data/lib/synthra/openapi_importer.rb +228 -0
  153. data/lib/synthra/output/json_formatter.rb +40 -0
  154. data/lib/synthra/output/ndjson_formatter.rb +55 -0
  155. data/lib/synthra/parser/ast.rb +1287 -0
  156. data/lib/synthra/parser/lexer.rb +1152 -0
  157. data/lib/synthra/parser/parser.rb +1664 -0
  158. data/lib/synthra/parser/tokens.rb +461 -0
  159. data/lib/synthra/performance_mode.rb +364 -0
  160. data/lib/synthra/personas.rb +397 -0
  161. data/lib/synthra/property_testing.rb +172 -0
  162. data/lib/synthra/quality_metrics.rb +405 -0
  163. data/lib/synthra/rails_test_helper.rb +248 -0
  164. data/lib/synthra/registry.rb +533 -0
  165. data/lib/synthra/relationships.rb +193 -0
  166. data/lib/synthra/repl/enhanced_repl.rb +607 -0
  167. data/lib/synthra/repl/formatter.rb +191 -0
  168. data/lib/synthra/scenarios.rb +423 -0
  169. data/lib/synthra/schema.rb +605 -0
  170. data/lib/synthra/schema_inheritance.rb +104 -0
  171. data/lib/synthra/schema_versioning.rb +212 -0
  172. data/lib/synthra/snapshot_testing.rb +199 -0
  173. data/lib/synthra/time_travel.rb +338 -0
  174. data/lib/synthra/type_definitions.rb +274 -0
  175. data/lib/synthra/types/address_location/addresses.rb +125 -0
  176. data/lib/synthra/types/address_location/airports.rb +200 -0
  177. data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
  178. data/lib/synthra/types/address_location/locations.rb +406 -0
  179. data/lib/synthra/types/base.rb +48 -0
  180. data/lib/synthra/types/commerce_products/commerce.rb +119 -0
  181. data/lib/synthra/types/commerce_products/companies.rb +71 -0
  182. data/lib/synthra/types/commerce_products/construction.rb +126 -0
  183. data/lib/synthra/types/commerce_products/products.rb +205 -0
  184. data/lib/synthra/types/core/collections.rb +513 -0
  185. data/lib/synthra/types/core/defaults.rb +76 -0
  186. data/lib/synthra/types/core/enums.rb +102 -0
  187. data/lib/synthra/types/core/identifiers.rb +445 -0
  188. data/lib/synthra/types/core/primitives.rb +586 -0
  189. data/lib/synthra/types/core/references.rb +466 -0
  190. data/lib/synthra/types/core/sequences.rb +304 -0
  191. data/lib/synthra/types/crypto/crypto.rb +162 -0
  192. data/lib/synthra/types/date_time/dates.rb +387 -0
  193. data/lib/synthra/types/finance_banking/banking.rb +424 -0
  194. data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
  195. data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
  196. data/lib/synthra/types/formula.rb +184 -0
  197. data/lib/synthra/types/health_medical/medical.rb +150 -0
  198. data/lib/synthra/types/hostile_payloads.rb +122 -0
  199. data/lib/synthra/types/json_array.rb +51 -0
  200. data/lib/synthra/types/media_entertainment/media.rb +62 -0
  201. data/lib/synthra/types/naughty_string.rb +30 -0
  202. data/lib/synthra/types/personal_names/chinese.rb +41 -0
  203. data/lib/synthra/types/personal_names/identifiers.rb +187 -0
  204. data/lib/synthra/types/personal_names/names.rb +246 -0
  205. data/lib/synthra/types/personal_names/national_id.rb +89 -0
  206. data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
  207. data/lib/synthra/types/regex.rb +248 -0
  208. data/lib/synthra/types/registry.rb +182 -0
  209. data/lib/synthra/types/repeating_element.rb +50 -0
  210. data/lib/synthra/types/scenario.rb +29 -0
  211. data/lib/synthra/types/technology_internet/apps.rb +67 -0
  212. data/lib/synthra/types/technology_internet/communication.rb +162 -0
  213. data/lib/synthra/types/technology_internet/devices.rb +80 -0
  214. data/lib/synthra/types/technology_internet/formats.rb +139 -0
  215. data/lib/synthra/types/technology_internet/networking.rb +143 -0
  216. data/lib/synthra/types/template.rb +92 -0
  217. data/lib/synthra/types/text_content/business.rb +128 -0
  218. data/lib/synthra/types/text_content/colors.rb +70 -0
  219. data/lib/synthra/types/text_content/misc.rb +237 -0
  220. data/lib/synthra/types/text_content/security.rb +130 -0
  221. data/lib/synthra/types/text_content/text_generation.rb +532 -0
  222. data/lib/synthra/types/travel/travel.rb +150 -0
  223. data/lib/synthra/utils/string_distance.rb +133 -0
  224. data/lib/synthra/validator/dsl_validator.rb +339 -0
  225. data/lib/synthra/validator/path_validator.rb +615 -0
  226. data/lib/synthra/version.rb +35 -0
  227. data/lib/synthra/webhook_simulator.rb +341 -0
  228. data/lib/synthra.rb +259 -0
  229. data/schemas/address.dsl +16 -0
  230. data/schemas/api_response.dsl +8 -0
  231. data/schemas/error_payload.dsl +9 -0
  232. data/schemas/order.dsl +10 -0
  233. data/schemas/order_item.dsl +8 -0
  234. data/schemas/payment.dsl +11 -0
  235. data/schemas/social_post.dsl +13 -0
  236. data/schemas/user.dsl +10 -0
  237. data/scripts/batch_fix_all.rb +96 -0
  238. data/scripts/delete_old_files.rb +32 -0
  239. data/scripts/fix_all_grouped_files.rb +137 -0
  240. data/scripts/fix_all_indentation.rb +48 -0
  241. data/scripts/fix_all_syntax.rb +124 -0
  242. data/scripts/fix_grouped_files.rb +184 -0
  243. data/scripts/fix_syntax_errors.rb +108 -0
  244. data/scripts/group_domain_types.rb +112 -0
  245. data/scripts/group_domain_types_fixed.rb +150 -0
  246. data/scripts/merge_domains_to_one_file.rb +68 -0
  247. data/scripts/move_existing_types.rb +130 -0
  248. data/scripts/split_grouped_types.rb +142 -0
  249. data/tech_docs/README.md +134 -0
  250. data/tech_docs/advanced/streaming.md +405 -0
  251. data/tech_docs/advanced/thread_safety.md +253 -0
  252. data/tech_docs/api/overview.md +485 -0
  253. data/tech_docs/appendices/type_chart.md +193 -0
  254. data/tech_docs/basic_concepts.md +383 -0
  255. data/tech_docs/behaviors/overview.md +346 -0
  256. data/tech_docs/dsl/complex_types.md +790 -0
  257. data/tech_docs/dsl/core_types.md +464 -0
  258. data/tech_docs/dsl/datetime_types.md +325 -0
  259. data/tech_docs/dsl/field_modifiers.md +414 -0
  260. data/tech_docs/dsl/grammar.md +431 -0
  261. data/tech_docs/dsl/schema_definition.md +399 -0
  262. data/tech_docs/export/README.md +276 -0
  263. data/tech_docs/installation.md +273 -0
  264. data/tech_docs/integration/ci_cd.md +707 -0
  265. data/tech_docs/integration/ci_cd_guide.md +579 -0
  266. data/tech_docs/integration/factory_bot.md +485 -0
  267. data/tech_docs/integration/rails.md +630 -0
  268. data/tech_docs/integration/rspec.md +449 -0
  269. data/tech_docs/modes/overview.md +350 -0
  270. data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
  271. data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
  272. data/tech_docs/quick_start.md +256 -0
  273. data/tech_docs/templates/README.md +805 -0
  274. data/tech_docs/tutorials/advanced.md +371 -0
  275. data/tech_docs/tutorials/getting_started.md +189 -0
  276. data/tech_docs/tutorials/intermediate.md +231 -0
  277. data/tech_docs/tutorials/template_gallery.md +569 -0
  278. data/tech_example/01_basic_usage.rb +238 -0
  279. data/tech_example/02_types_demo.rb +336 -0
  280. data/tech_example/04_cli_usage.md +429 -0
  281. data/tech_example/05_database_seeding.rb +283 -0
  282. data/tech_example/07_rspec_integration.rb +359 -0
  283. data/tech_example/10_custom_types.rb +387 -0
  284. data/tech_example/12_behaviors.rb +372 -0
  285. data/tech_example/13_twitter_dm_example.rb +120 -0
  286. data/tech_example/14_exact_json_structure.rb +253 -0
  287. data/tech_example/16_lsp_server.rb +56 -0
  288. data/tech_example/17_property_testing.rb +92 -0
  289. data/tech_example/18_enhanced_repl.rb +120 -0
  290. data/tech_example/19_security_fuzzing.rb +145 -0
  291. data/tech_example/NEW_FEATURES.md +169 -0
  292. data/tech_example/README.md +118 -0
  293. data/tech_example/schemas/api_response.dsl +123 -0
  294. data/tech_example/schemas/ecommerce.dsl +121 -0
  295. data/tech_example/schemas/twitter_dm.dsl +109 -0
  296. data/tech_example/schemas/user.dsl +36 -0
  297. data/vscode-extension/README.md +246 -0
  298. data/vscode-extension/language-configuration.json +31 -0
  299. data/vscode-extension/package.json +55 -0
  300. data/vscode-extension/snippets/fakedatadsl.json +198 -0
  301. data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
  302. metadata +478 -0
@@ -0,0 +1,461 @@
1
+ # frozen_string_literal: true
2
+
3
+ # =============================================================================
4
+
5
+ # Synthra Token Definitions
6
+ # =============================================================================
7
+ #
8
+ # This file defines all token types recognized by the DSL lexer and the
9
+ # Token class used to represent individual tokens.
10
+ #
11
+ # The lexer converts DSL source text into a stream of Token objects,
12
+ # which the parser then uses to build an AST.
13
+ #
14
+ # @example Token stream for "User:"
15
+ # Token(:schema_name, "User", line: 1, column: 1)
16
+ # Token(:colon, ":", line: 1, column: 5)
17
+ #
18
+ # @example Token stream for "name: text"
19
+ # Token(:field_name, "name", line: 2, column: 3)
20
+ # Token(:colon, ":", line: 2, column: 7)
21
+ # Token(:type, "text", line: 2, column: 9)
22
+ #
23
+ # =============================================================================
24
+
25
+
26
+ module Synthra
27
+ module Parser
28
+
29
+ # Token type constants for the DSL lexer
30
+ #
31
+ # This module defines all the token types that the lexer can produce.
32
+ # Each token type is a symbol that identifies the kind of syntax element.
33
+ #
34
+ # Token types are organized into categories:
35
+ # - **Structural**: Schema and field names, colons, question marks
36
+ # - **Types**: Type names, Ref keyword
37
+ # - **Delimiters**: Parentheses, commas, dots
38
+ # - **Values**: Numbers, strings, identifiers, ranges, percentages
39
+ # - **Keywords**: if, true, false
40
+ # - **Behaviors**: @ prefixed behavior declarations
41
+ # - **Whitespace/Structure**: Newlines, indentation changes
42
+ # - **Special**: EOF, symbols
43
+ #
44
+ # @example Check if a token is a type
45
+ # token.type == Tokens::TYPE
46
+ #
47
+ # @example Check if token type is valid
48
+ # Tokens::ALL.include?(:type) # => true
49
+ #
50
+
51
+ module Tokens
52
+ # ==========================================================================
53
+
54
+ # Structural Tokens
55
+ # ==========================================================================
56
+ # These tokens define the structure of schemas and fields
57
+
58
+ # Schema name at the top level (e.g., "User:")
59
+ # Value: String containing the schema name without the colon
60
+ # @example "User:" => Token(:schema_name, "User")
61
+
62
+ SCHEMA_NAME = :schema_name
63
+
64
+ # Field name within a schema (e.g., "name:", "email?:")
65
+ # Value: String containing the field name (may include ? for optional)
66
+ # @example "email?:" => Token(:field_name, "email?")
67
+
68
+ FIELD_NAME = :field_name
69
+
70
+ # Colon separator
71
+ # Value: ":" literal
72
+ # @example ":" => Token(:colon, ":")
73
+
74
+ COLON = :colon
75
+
76
+ # Question mark for optional/nullable types
77
+ # Value: "?" literal
78
+ # @example "?" => Token(:question, "?")
79
+
80
+ QUESTION = :question
81
+
82
+ # ==========================================================================
83
+
84
+ # Type Tokens
85
+ # ==========================================================================
86
+ # These tokens represent type declarations
87
+
88
+ # Built-in or custom type name (uuid, text, number, etc.)
89
+ # Value: String containing the type name
90
+ # @example "uuid" => Token(:type, "uuid")
91
+
92
+ TYPE = :type
93
+
94
+ # Reference keyword for cross-schema references
95
+ # Value: "Ref" literal
96
+ # @example "Ref" => Token(:ref, "Ref")
97
+
98
+ REF = :ref
99
+
100
+ # ==========================================================================
101
+
102
+ # Delimiter Tokens
103
+ # ==========================================================================
104
+ # These tokens separate or group elements
105
+
106
+ # Left parenthesis for type arguments
107
+ # Value: "(" literal
108
+ # @example "(" => Token(:lparen, "(")
109
+
110
+ LPAREN = :lparen
111
+
112
+ # Right parenthesis for type arguments
113
+ # Value: ")" literal
114
+ # @example ")" => Token(:rparen, ")")
115
+
116
+ RPAREN = :rparen
117
+
118
+ # Comma separator in argument lists
119
+ # Value: "," literal
120
+ # @example "," => Token(:comma, ",")
121
+
122
+ COMMA = :comma
123
+
124
+ # Dot separator in references (Schema.field)
125
+ # Value: "." literal
126
+ # @example "." => Token(:dot, ".")
127
+
128
+ DOT = :dot
129
+
130
+ # Minus sign for negative numbers
131
+ # Value: "-" literal
132
+ # @example "-" => Token(:minus, "-")
133
+
134
+ MINUS = :minus
135
+
136
+ # Arithmetic operators (used inside formula(...) expressions)
137
+ # @example "*" => Token(:star, "*")
138
+ STAR = :star
139
+
140
+ # @example "/" => Token(:slash, "/")
141
+ SLASH = :slash
142
+
143
+ # @example "+" => Token(:plus, "+")
144
+ PLUS = :plus
145
+
146
+ # ==========================================================================
147
+
148
+ # Value Tokens
149
+ # ==========================================================================
150
+ # These tokens represent literal values
151
+
152
+ # Numeric literal (integer or float)
153
+ # Value: Integer or Float
154
+ # @example "123" => Token(:number, 123)
155
+ # @example "3.14" => Token(:number, 3.14)
156
+
157
+ NUMBER = :number
158
+
159
+ # String literal (single or double quoted)
160
+ # Value: String (quotes stripped)
161
+ # @example '"hello"' => Token(:string, "hello")
162
+
163
+ STRING = :string
164
+
165
+ # Identifier (unquoted name, used in enums, etc.)
166
+ # Value: String
167
+ # @example "pending" => Token(:identifier, "pending")
168
+
169
+ IDENTIFIER = :identifier
170
+
171
+ # Range literal (min..max)
172
+ # Value: Range object
173
+ # @example "18..80" => Token(:range, 18..80)
174
+
175
+ RANGE = :range
176
+
177
+ # Percentage literal
178
+ # Value: Integer (percent without %)
179
+ # @example "50%" => Token(:percent, 50)
180
+
181
+ PERCENT = :percent
182
+
183
+ # ==========================================================================
184
+
185
+ # Keyword Tokens
186
+ # ==========================================================================
187
+ # These tokens represent reserved keywords
188
+
189
+ # Conditional keyword for field conditions
190
+ # Value: "if" literal
191
+ # @example "if" => Token(:if, "if")
192
+
193
+ IF = :if
194
+
195
+ # Boolean true keyword
196
+ # Value: true
197
+ # @example "true" => Token(:true, true)
198
+
199
+ TRUE_KW = :true
200
+
201
+ # Boolean false keyword
202
+ # Value: false
203
+ # @example "false" => Token(:false, false)
204
+
205
+ FALSE_KW = :false
206
+
207
+ # ==========================================================================
208
+
209
+ # Simulyra DSL Keywords
210
+ # ==========================================================================
211
+ # These tokens are specific to the Simulyra layered DSL structure
212
+
213
+ # Schema definition keyword
214
+ # Value: "schema" literal
215
+ # @example "schema User:" => Token(:schema_keyword, "schema")
216
+
217
+ SCHEMA_KEYWORD = :schema_keyword
218
+
219
+ # API definition keyword
220
+ # Value: "api" literal
221
+ # @example "api GET /users:" => Token(:api_keyword, "api")
222
+
223
+ API_KEYWORD = :api_keyword
224
+
225
+ # Scenario definition keyword
226
+ # Value: "scenario" literal
227
+ # @example "scenario Success:" => Token(:scenario_keyword, "scenario")
228
+
229
+ SCENARIO_KEYWORD = :scenario_keyword
230
+
231
+ # HTTP method token
232
+ # Value: Symbol (:get, :post, :put, :patch, :delete, :options, :head)
233
+ # @example "GET" => Token(:http_method, :get)
234
+
235
+ HTTP_METHOD = :http_method
236
+
237
+ # URL path token
238
+ # Value: String containing the path
239
+ # @example "/users/:id" => Token(:path, "/users/:id")
240
+
241
+ PATH = :path
242
+
243
+ # Schema reference token for explicit schema(:Name) syntax
244
+ # Value: String containing the schema name
245
+ # @example "schema(:User)" => Token(:schema_ref, "User")
246
+
247
+ SCHEMA_REF = :schema_ref
248
+
249
+ # ==========================================================================
250
+
251
+ # Behavior Tokens
252
+ # ==========================================================================
253
+ # These tokens represent behavior declarations
254
+
255
+ # Behavior annotation (@latency, @failure, etc.)
256
+ # Value: String containing behavior name without @
257
+ # @example "@latency" => Token(:at_behavior, "latency")
258
+
259
+ AT_BEHAVIOR = :at_behavior
260
+
261
+ # ==========================================================================
262
+
263
+ # Whitespace/Structure Tokens
264
+ # ==========================================================================
265
+ # These tokens represent structural elements based on whitespace
266
+
267
+ # Newline character
268
+ # Value: "\n" literal
269
+ # @example "\n" => Token(:newline, "\n")
270
+
271
+ NEWLINE = :newline
272
+
273
+ # Increase in indentation level
274
+ # Value: Integer (new indentation level)
275
+ # @example Indent from 0 to 2 => Token(:indent, 2)
276
+
277
+ INDENT = :indent
278
+
279
+ # Decrease in indentation level
280
+ # Value: Integer (new indentation level)
281
+ # @example Dedent from 4 to 2 => Token(:dedent, 2)
282
+
283
+ DEDENT = :dedent
284
+
285
+ # ==========================================================================
286
+
287
+ # Special Tokens
288
+ # ==========================================================================
289
+ # These tokens have special meaning
290
+
291
+ # End of file marker
292
+ # Value: nil
293
+ # @example End of input => Token(:eof, nil)
294
+
295
+ EOF = :eof
296
+
297
+ # Ruby symbol literal (:function_name)
298
+ # Value: Symbol
299
+ # @example ":compute" => Token(:symbol, :compute)
300
+
301
+ SYMBOL = :symbol
302
+
303
+ # ==========================================================================
304
+
305
+ # Token Type Collection
306
+ # ==========================================================================
307
+
308
+ # Array of all valid token types
309
+ #
310
+ # @return [Array<Symbol>] all token type symbols
311
+ #
312
+ # @example Validate token type
313
+ # Tokens::ALL.include?(token.type) # => true/false
314
+ #
315
+
316
+ ALL = [
317
+ SCHEMA_NAME, FIELD_NAME, COLON, QUESTION,
318
+ TYPE, REF,
319
+ LPAREN, RPAREN, COMMA, DOT, MINUS,
320
+ NUMBER, STRING, IDENTIFIER, RANGE, PERCENT,
321
+ IF, TRUE_KW, FALSE_KW,
322
+ SCHEMA_KEYWORD, API_KEYWORD, SCENARIO_KEYWORD, HTTP_METHOD, PATH, SCHEMA_REF,
323
+ AT_BEHAVIOR,
324
+ NEWLINE, INDENT, DEDENT,
325
+ EOF, SYMBOL
326
+ ].freeze
327
+ end
328
+
329
+ # Represents a single token from the lexer
330
+ #
331
+ # A Token captures the type, value, and source location of a syntax
332
+ # element in the DSL. Tokens are produced by the Lexer and consumed
333
+ # by the Parser.
334
+ #
335
+ # @example Create a token
336
+ # token = Token.new(:type, "uuid", line: 5, column: 10)
337
+ # token.type # => :type
338
+ # token.value # => "uuid"
339
+ # token.line # => 5
340
+ # token.column # => 10
341
+ #
342
+ # @example Check token type
343
+ # token.type?(:type) # => true
344
+ # token.type?(:number) # => false
345
+ #
346
+
347
+ class Token
348
+
349
+ # @!attribute [r] type
350
+ # The token type (one of Tokens::ALL)
351
+ # @return [Symbol] the token type
352
+
353
+ attr_reader :type
354
+
355
+ # @!attribute [r] value
356
+ # The token value (varies by type)
357
+ # @return [Object] the token value
358
+
359
+ attr_reader :value
360
+
361
+ # @!attribute [r] line
362
+ # Source line number (1-based)
363
+ # @return [Integer] line number
364
+
365
+ attr_reader :line
366
+
367
+ # @!attribute [r] column
368
+ # Source column number (1-based)
369
+ # @return [Integer] column number
370
+
371
+ attr_reader :column
372
+
373
+ # Create a new Token
374
+ #
375
+ # @param type [Symbol] the token type (should be in Tokens::ALL)
376
+ # @param value [Object] the token value
377
+ # @param line [Integer] line number where token appears (1-based)
378
+ # @param column [Integer] column where token starts (1-based)
379
+ #
380
+ # @example
381
+ # Token.new(:number, 42, line: 3, column: 15)
382
+ #
383
+
384
+ def initialize(type, value, line:, column:)
385
+ @type = type
386
+ @value = value
387
+ @line = line
388
+ @column = column
389
+ end
390
+
391
+ # String representation for debugging
392
+ #
393
+ # @return [String] human-readable token description
394
+ #
395
+ # @example
396
+ # token.to_s # => "Token(type, \"uuid\", line: 5, col: 10)"
397
+ #
398
+
399
+ def to_s
400
+ "Token(#{type}, #{value.inspect}, line: #{line}, col: #{column})"
401
+ end
402
+
403
+ # Inspect output (same as to_s)
404
+ #
405
+ # @return [String] inspect representation
406
+ #
407
+
408
+ def inspect
409
+ to_s
410
+ end
411
+
412
+ # Check equality with another token
413
+ #
414
+ # Two tokens are equal if they have the same type and value.
415
+ # Line and column are not considered for equality.
416
+ #
417
+ # @param other [Token] token to compare
418
+ # @return [Boolean] true if type and value match
419
+ #
420
+ # @example
421
+ # token1 = Token.new(:type, "uuid", line: 1, column: 1)
422
+ # token2 = Token.new(:type, "uuid", line: 2, column: 5)
423
+ # token1 == token2 # => true (same type and value)
424
+ #
425
+
426
+ def ==(other)
427
+ return false unless other.is_a?(Token)
428
+
429
+ type == other.type && value == other.value
430
+ end
431
+
432
+ # Alias for == to support Hash key comparison
433
+ alias eql? ==
434
+
435
+ # Hash code for use in Hash keys and Sets
436
+ #
437
+ # Based on type and value only (not line/column).
438
+ #
439
+ # @return [Integer] hash code
440
+ #
441
+
442
+ def hash
443
+ [type, value].hash
444
+ end
445
+
446
+ # Check if token is of a specific type
447
+ #
448
+ # @param expected_type [Symbol] type to check against
449
+ # @return [Boolean] true if token type matches
450
+ #
451
+ # @example
452
+ # token.type?(:type) # => true
453
+ # token.type?(:number) # => false
454
+ #
455
+
456
+ def type?(expected_type)
457
+ type == expected_type
458
+ end
459
+ end
460
+ end
461
+ end