Module: Ea::Sources::Qea::Xref::Parser
- Defined in:
- lib/ea/sources/qea/xref/parser.rb
Overview
Pure parser for EA's t_xref.Description mini-language.
Stateless — every call returns a fresh Xref::Record.
Supported formats:
@STEREO;Name=X;FQName=Y;@ENDSTEREO;
@PROP=@NAME=..@ENDNAME;@TYPE=..@ENDTYPE;@VALU=..@ENDVALU;@PRMT=..@ENDPRMT;@ENDPROP;
<key>=<value>;<key>=<value>;
Unknown formats fall through to key=value parsing.
Constant Summary collapse
- STEREO_REGEX =
Matches both legacy
@STEREO;Name=X;GUID={..};and the plateau form@STEREO;Name=X;FQName=Y;@ENDSTEREO;. / @STEREO; (.*?) (?:@ENDSTEREO;|\z) /mx.freeze
- PROP_REGEX =
One Description can carry multiple @PROP=...@ENDPROP; blocks. Split, then classify each as PropertyDefinition or LegendDefinition.
/ @PROP= (.*?) @ENDPROP; /mx.freeze
Class Method Summary collapse
- .build_prop_record(block) ⇒ Object
-
.extract_tagged_value(block, tag) ⇒ Object
Extracts the content between @TAG=...@ENDTAG; markers.
-
.parse(description) ⇒ Ea::Sources::Qea::Xref::Record
Parse one Description string into a typed Record.
-
.parse_color_value(value) ⇒ Object
EA encodes legend VALU as
#key#=value;pairs. -
.parse_key_values(description) ⇒ Object
Legacy
Key=Value;Key=Value;parsing. - .parse_legends(description) ⇒ Object
- .parse_properties(description) ⇒ Object
-
.parse_semicolon_fields(body) ⇒ Object
Parse
Key=Value;Key=value;into a string-keyed hash. - .parse_stereotype(description) ⇒ Object
Class Method Details
.build_prop_record(block) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 77 def build_prop_record(block) name = extract_tagged_value(block, "NAME") type = extract_tagged_value(block, "TYPE") value = extract_tagged_value(block, "VALU") parameter = extract_tagged_value(block, "PRMT") if type&.start_with?("LEGEND_") LegendDefinition.new( name: name, legend_type: type, colors: parse_color_value(value), parameter: parameter ) else PropertyDefinition.new( name: name, type: type, value: value, parameter: parameter ) end end |
.extract_tagged_value(block, tag) ⇒ Object
Extracts the content between @TAG=...@ENDTAG; markers. Returns nil when the tag is absent.
102 103 104 105 106 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 102 def extract_tagged_value(block, tag) pattern = /@#{tag}=(.*?)@END#{tag};/m.freeze match = block.match(pattern) match ? match[1] : nil end |
.parse(description) ⇒ Ea::Sources::Qea::Xref::Record
Parse one Description string into a typed Record.
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 22 def parse(description) return Record.new if description.nil? || description.empty? Record.new( stereotype: parse_stereotype(description), properties: parse_properties(description), legends: parse_legends(description), key_values: parse_key_values(description), raw: description ) end |
.parse_color_value(value) ⇒ Object
EA encodes legend VALU as #key#=value; pairs.
Returns a hash keyed by underscored symbol.
110 111 112 113 114 115 116 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 110 def parse_color_value(value) return {} if value.nil? || value.empty? value.scan(/#([^#=]+)#=([^;]*);/).each_with_object({}) do |(k, v), acc| acc[k.downcase.to_sym] = v end end |
.parse_key_values(description) ⇒ Object
Legacy Key=Value;Key=Value; parsing. Skips content that
looks like @STEREO or @PROP blocks to avoid noise.
120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 120 def parse_key_values(description) stripped = description .gsub(/@STEREO;.*?(?:@ENDSTEREO;|\z)/m, "") .gsub(/@PROP=.*?@ENDPROP;/m, "") pairs = stripped.split(";").map { |s| s.split("=", 2) } pairs.each_with_object({}) do |(k, v), acc| next if k.nil? || k.empty? || v.nil? acc[k.downcase.to_sym] = v end end |
.parse_legends(description) ⇒ Object
71 72 73 74 75 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 71 def parse_legends(description) parse_properties(description).select do |prop| prop.is_a?(LegendDefinition) end end |
.parse_properties(description) ⇒ Object
63 64 65 66 67 68 69 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 63 def parse_properties(description) blocks = description.scan(PROP_REGEX).flatten blocks.each_with_object([]) do |block, acc| record = build_prop_record(block) acc << record if record end end |
.parse_semicolon_fields(body) ⇒ Object
Parse Key=Value;Key=value; into a string-keyed hash.
Used internally for the @STEREO body fields.
134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 134 def parse_semicolon_fields(body) body.split(";").each_with_object({}) do |part, acc| key, value = part.split("=", 2) next if key.nil? || key.empty? || value.nil? # Strip @END* terminators that may be attached when the # body wasn't cleanly split (defensive — usually already # consumed by STEREO_REGEX). cleaned = value.sub(/@END\w+\z/, "") acc[key] = cleaned end end |
.parse_stereotype(description) ⇒ Object
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/ea/sources/qea/xref/parser.rb', line 44 def parse_stereotype(description) match = description.match(STEREO_REGEX) return nil unless match fields = parse_semicolon_fields(match[1]) StereotypeApplication.new( name: fields["Name"], fqname: fields["FQName"] ) end |