expressir 2.3.7 → 2.4.1
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.
- checksums.yaml +4 -4
- data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
- data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
- data/TODO.bugs/03-builder-mutable-state.md +43 -0
- data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
- data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
- data/TODO.bugs/06-collection-registry-single-source.md +53 -0
- data/TODO.bugs/07-require-relative-cleanup.md +42 -0
- data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
- data/TODO.bugs/09-parser-split.md +53 -0
- data/TODO.bugs/10-to-s-override.md +42 -0
- data/TODO.bugs/11-parser-class-variables.md +39 -0
- data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
- data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
- data/TODO.bugs/14-model-formatting-leak.md +30 -0
- data/TODO.bugs/15-expression-children-macro.md +27 -0
- data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
- data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
- data/TODO.bugs/18-const-get-private-constants.md +30 -0
- data/TODO.bugs/19-format-methods-public.md +22 -0
- data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
- data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
- data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
- data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
- data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
- data/TODO.bugs/25-debug-puts-in-production.md +21 -0
- data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
- data/TODO.bugs/27-package-build-god-method.md +19 -0
- data/TODO.bugs/28-package-god-class.md +30 -0
- data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
- data/TODO.bugs/30-unicode-map-extraction.md +19 -0
- data/TODO.bugs/README.md +43 -0
- data/docs/_tutorials/formatting-schemas.adoc +89 -0
- data/docs/_tutorials/index.adoc +10 -0
- data/docs/lychee.toml +3 -0
- data/expressir.gemspec +4 -2
- data/lib/expressir/commands/changes_import_eengine.rb +0 -6
- data/lib/expressir/commands/changes_validate.rb +0 -2
- data/lib/expressir/commands/clean.rb +1 -1
- data/lib/expressir/commands/file_violations.rb +70 -0
- data/lib/expressir/commands/format.rb +1 -1
- data/lib/expressir/commands/non_ascii_character.rb +49 -0
- data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
- data/lib/expressir/commands/package.rb +138 -185
- data/lib/expressir/commands/validate_ascii.rb +0 -510
- data/lib/expressir/commands/version.rb +1 -1
- data/lib/expressir/commands.rb +3 -0
- data/lib/expressir/coverage.rb +49 -117
- data/lib/expressir/express/builder.rb +74 -86
- data/lib/expressir/express/builder_context.rb +22 -0
- data/lib/expressir/express/builders/expression_builder.rb +16 -16
- data/lib/expressir/express/cache.rb +35 -8
- data/lib/expressir/express/error.rb +7 -0
- data/lib/expressir/express/formatter.rb +33 -18
- data/lib/expressir/express/formatters/declarations_formatter.rb +24 -2
- data/lib/expressir/express/formatters/remark_formatter.rb +75 -2
- data/lib/expressir/express/formatters/statements_formatter.rb +20 -3
- data/lib/expressir/express/grammar/parser.rb +705 -0
- data/lib/expressir/express/grammar.rb +11 -0
- data/lib/expressir/express/line_map.rb +48 -0
- data/lib/expressir/express/node_position_index.rb +215 -0
- data/lib/expressir/express/parser.rb +114 -884
- data/lib/expressir/express/pretty_formatter.rb +23 -5
- data/lib/expressir/express/remark_attacher.rb +483 -669
- data/lib/expressir/express/remark_scanner.rb +245 -0
- data/lib/expressir/express/schema_block_scanner.rb +136 -0
- data/lib/expressir/express/schema_source_formatter.rb +15 -0
- data/lib/expressir/express/scope_resolver.rb +194 -0
- data/lib/expressir/express/source_formatter.rb +15 -0
- data/lib/expressir/express/streaming_builder.rb +147 -176
- data/lib/expressir/express.rb +10 -6
- data/lib/expressir/model/concerns.rb +3 -0
- data/lib/expressir/model/data_types/generic_entity.rb +6 -6
- data/lib/expressir/model/declarations/entity.rb +5 -0
- data/lib/expressir/model/declarations/function.rb +5 -0
- data/lib/expressir/model/declarations/procedure.rb +5 -0
- data/lib/expressir/model/declarations/rule.rb +6 -0
- data/lib/expressir/model/declarations/schema.rb +21 -8
- data/lib/expressir/model/declarations/type.rb +3 -0
- data/lib/expressir/model/exp_file.rb +2 -0
- data/lib/expressir/model/expressions/aggregate_initializer.rb +1 -0
- data/lib/expressir/model/expressions/aggregate_initializer_item.rb +1 -0
- data/lib/expressir/model/expressions/binary_expression.rb +1 -0
- data/lib/expressir/model/expressions/entity_constructor.rb +1 -0
- data/lib/expressir/model/expressions/function_call.rb +1 -0
- data/lib/expressir/model/expressions/interval.rb +1 -0
- data/lib/expressir/model/expressions/query_expression.rb +2 -0
- data/lib/expressir/model/expressions/unary_expression.rb +1 -0
- data/lib/expressir/model/model_element.rb +128 -14
- data/lib/expressir/model/remark_format.rb +17 -0
- data/lib/expressir/model/remark_info.rb +31 -3
- data/lib/expressir/model/remark_placement.rb +29 -0
- data/lib/expressir/model/statements/alias.rb +2 -0
- data/lib/expressir/model/statements/assignment.rb +4 -0
- data/lib/expressir/model/statements/case.rb +21 -0
- data/lib/expressir/model/statements/case_action.rb +1 -0
- data/lib/expressir/model/statements/compound.rb +4 -0
- data/lib/expressir/model/statements/escape.rb +3 -0
- data/lib/expressir/model/statements/if.rb +5 -0
- data/lib/expressir/model/statements/null.rb +3 -0
- data/lib/expressir/model/statements/procedure_call.rb +3 -0
- data/lib/expressir/model/statements/repeat.rb +3 -0
- data/lib/expressir/model/statements/return.rb +3 -0
- data/lib/expressir/model/statements/skip.rb +3 -0
- data/lib/expressir/model.rb +12 -3
- data/lib/expressir/package/builder.rb +2 -2
- data/lib/expressir/version.rb +6 -1
- data/lib/expressir.rb +38 -3
- metadata +65 -5
- data/lib/expressir/express/transformer/remark_handling.rb +0 -194
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parsanol"
|
|
4
|
+
|
|
5
|
+
module Expressir
|
|
6
|
+
module Express
|
|
7
|
+
module Grammar
|
|
8
|
+
# EXPRESS grammar definition: ~250 Parsanol rules implementing
|
|
9
|
+
# ISO 10303-11 concrete syntax.
|
|
10
|
+
#
|
|
11
|
+
# Extracted from the outer Parser class so grammar changes land in
|
|
12
|
+
# one focused file, separate from the I/O orchestration on the
|
|
13
|
+
# Parser facade (lib/expressir/express/parser.rb).
|
|
14
|
+
class Parser < Parsanol::Parser
|
|
15
|
+
root(:syntax)
|
|
16
|
+
|
|
17
|
+
# Class instance variables for caching (not @@ class variables,
|
|
18
|
+
# which are shared across the entire hierarchy). These are scoped
|
|
19
|
+
# to this class only. Accessed via @var within class methods.
|
|
20
|
+
@cached_grammar_json = nil
|
|
21
|
+
@cached_grammar_atom_id = nil
|
|
22
|
+
@cached_parser = nil
|
|
23
|
+
@parser_mutex = Mutex.new
|
|
24
|
+
@cached_schema_grammar_json = nil
|
|
25
|
+
|
|
26
|
+
# Threshold for using memory-bounded fresh parse (bytes)
|
|
27
|
+
# Files above this use parse_fresh which has no packrat cache
|
|
28
|
+
LARGE_FILE_THRESHOLD = 1024 * 1024 # 1 MB
|
|
29
|
+
|
|
30
|
+
# Get cached parser instance (thread-safe)
|
|
31
|
+
# Reusing the parser avoids the overhead of reinitializing all rule definitions
|
|
32
|
+
def self.cached_parser
|
|
33
|
+
return @cached_parser if @cached_parser
|
|
34
|
+
|
|
35
|
+
@parser_mutex.synchronize do
|
|
36
|
+
@cached_parser ||= new
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Clear the cached parser (useful for testing or after grammar changes)
|
|
41
|
+
def self.clear_parser_cache
|
|
42
|
+
@parser_mutex.synchronize do
|
|
43
|
+
@cached_parser = nil
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Check if native parsing is available
|
|
48
|
+
def self.native_available?
|
|
49
|
+
return @native_available unless @native_available.nil?
|
|
50
|
+
|
|
51
|
+
@native_available = begin
|
|
52
|
+
require "parsanol/native"
|
|
53
|
+
Parsanol::Native.available?
|
|
54
|
+
rescue LoadError
|
|
55
|
+
false
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Get cached grammar JSON for native parsing
|
|
60
|
+
def self.cached_grammar_json
|
|
61
|
+
return @cached_grammar_json if @cached_grammar_json
|
|
62
|
+
|
|
63
|
+
parser = new
|
|
64
|
+
atom = parser.syntax
|
|
65
|
+
|
|
66
|
+
# Cache by atom object_id
|
|
67
|
+
if atom.object_id != @cached_grammar_atom_id
|
|
68
|
+
@cached_grammar_atom_id = atom.object_id
|
|
69
|
+
@cached_grammar_json = Parsanol::Native.serialize_grammar(atom)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@cached_grammar_json
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Get cached grammar JSON for schemaDecl (used for streaming parse)
|
|
76
|
+
def self.cached_schema_grammar_json
|
|
77
|
+
return @cached_schema_grammar_json if @cached_schema_grammar_json
|
|
78
|
+
|
|
79
|
+
schema_atom = cached_parser.schemaDecl
|
|
80
|
+
@cached_schema_grammar_json = Parsanol::Native.serialize_grammar(schema_atom)
|
|
81
|
+
@cached_schema_grammar_json
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Parse using native engine with Rust-side transformation (fastest)
|
|
85
|
+
#
|
|
86
|
+
# This method provides ~17x speedup over pure Ruby parsing.
|
|
87
|
+
# The transformation happens in Rust using to_parslet_compatible,
|
|
88
|
+
# producing Parslet-compatible output that Builder.build can consume directly.
|
|
89
|
+
#
|
|
90
|
+
# @param source [String] EXPRESS source code to parse
|
|
91
|
+
# @return [Hash, Array] Transformed AST in Parslet-compatible format
|
|
92
|
+
# @raise [LoadError] If native parser is not available
|
|
93
|
+
def self.parse_native(source)
|
|
94
|
+
unless native_available?
|
|
95
|
+
raise LoadError, "Native parser not available"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
grammar_atom = cached_parser.syntax
|
|
99
|
+
# Use fresh-parse (no cache) for large files to bound memory
|
|
100
|
+
if source.bytesize > LARGE_FILE_THRESHOLD
|
|
101
|
+
Parsanol::Native.parse_fresh(grammar_atom, source)
|
|
102
|
+
else
|
|
103
|
+
Parsanol::Native.parse(grammar_atom, source)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def cts(atom)
|
|
108
|
+
spaces >> atom
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def cstr(atom)
|
|
112
|
+
cts(str(atom).as(:str))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
KEYWORDS = %i[
|
|
116
|
+
ABS ABSTRACT ACOS AGGREGATE ALIAS AND ANDOR ARRAY AS ASIN ATAN BAG BASED_ON
|
|
117
|
+
BEGIN BINARY BLENGTH BOOLEAN BY CASE CONSTANT CONST_E COS DERIVE DIV ELSE
|
|
118
|
+
END END_ALIAS END_CASE END_CONSTANT END_ENTITY END_FUNCTION END_IF
|
|
119
|
+
END_LOCAL END_PROCEDURE END_REPEAT END_RULE END_SCHEMA
|
|
120
|
+
END_SUBTYPE_CONSTRAINT END_TYPE ENTITY ENUMERATION ESCAPE EXISTS EXP
|
|
121
|
+
EXTENSIBLE FALSE FIXED FOR FORMAT FROM FUNCTION GENERIC GENERIC_ENTITY
|
|
122
|
+
HIBOUND HIINDEX IF IN INSERT INTEGER INVERSE LENGTH LIKE LIST LOBOUND LOCAL
|
|
123
|
+
LOG LOG10 LOG2 LOGICAL LOINDEX MOD NOT NUMBER NVL ODD OF ONEOF OPTIONAL OR
|
|
124
|
+
OTHERWISE PI PROCEDURE QUERY REAL REFERENCE REMOVE RENAMED REPEAT RETURN
|
|
125
|
+
ROLESOF RULE SCHEMA SELECT SELF SET SIN SIZEOF SKIP SQRT STRING SUBTYPE
|
|
126
|
+
SUBTYPE_CONSTRAINT SUPERTYPE TAN THEN TO TRUE TYPE TYPEOF TOTAL_OVER UNIQUE
|
|
127
|
+
UNKNOWN UNTIL USE USEDIN VALUE VALUE_IN VALUE_UNIQUE VAR WITH WHERE WHILE
|
|
128
|
+
XOR
|
|
129
|
+
].freeze
|
|
130
|
+
|
|
131
|
+
def keyword_rule(str)
|
|
132
|
+
key_chars = str.to_s.chars
|
|
133
|
+
key_chars
|
|
134
|
+
.collect! { |char| match("[#{char}#{char.downcase}]") }
|
|
135
|
+
.reduce(:>>) >> match["a-zA-Z0-9_"].absent?
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
KEYWORDS.each do |keyword|
|
|
139
|
+
sym = :"t#{keyword}"
|
|
140
|
+
rule(sym) { cts(keyword_rule(keyword).as(:str)).as(sym) }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
rule(:abstractEntityDeclaration) do
|
|
144
|
+
tABSTRACT.as(:abstractEntityDeclaration)
|
|
145
|
+
end
|
|
146
|
+
rule(:abstractSupertypeDeclaration) do
|
|
147
|
+
(tABSTRACT >> tSUPERTYPE >> subtypeConstraint.maybe).as(:abstractSupertypeDeclaration)
|
|
148
|
+
end
|
|
149
|
+
rule(:abstractSupertype) do
|
|
150
|
+
(tABSTRACT >> tSUPERTYPE >> op_delim).as(:abstractSupertype)
|
|
151
|
+
end
|
|
152
|
+
rule(:actualParameterList) do
|
|
153
|
+
(op_leftparen >> (parameter >> (op_comma >> parameter).repeat).as(:listOf_parameter).maybe >> op_rightparen)
|
|
154
|
+
.as(:actualParameterList)
|
|
155
|
+
end
|
|
156
|
+
rule(:addLikeOp) { (op_plus | op_minus | tOR | tXOR).as(:addLikeOp) }
|
|
157
|
+
rule(:aggregateInitializer) do
|
|
158
|
+
(op_leftbracket >> (element >> (op_comma >> element).repeat).as(:listOf_element).maybe >> op_rightbracket)
|
|
159
|
+
.as(:aggregateInitializer)
|
|
160
|
+
end
|
|
161
|
+
rule(:aggregateSource) { simpleExpression.as(:aggregateSource) }
|
|
162
|
+
rule(:aggregateType) do
|
|
163
|
+
(tAGGREGATE >> (op_colon >> typeLabel).maybe >> tOF >> parameterType).as(:aggregateType)
|
|
164
|
+
end
|
|
165
|
+
rule(:aggregationTypes) do
|
|
166
|
+
(arrayType | bagType | listType | setType).as(:aggregationTypes)
|
|
167
|
+
end
|
|
168
|
+
rule(:algorithmHead) do
|
|
169
|
+
(declaration.repeat.as(:declaration) >> constantDecl.maybe >> localDecl.maybe).as(:algorithmHead)
|
|
170
|
+
end
|
|
171
|
+
rule(:aliasStmt) do
|
|
172
|
+
(tALIAS >> variableId >> tFOR >> generalRef >> qualifier.repeat.as(:qualifier) >>
|
|
173
|
+
op_delim >> stmt.repeat(1).as(:stmt) >> tEND_ALIAS >> op_delim.as(:op_delim2)).as(:aliasStmt)
|
|
174
|
+
end
|
|
175
|
+
rule(:anyKeyword) { KEYWORDS.map { |kw| send("t#{kw}") }.inject(:|) }
|
|
176
|
+
rule(:arrayType) do
|
|
177
|
+
(tARRAY >> boundSpec >> tOF >> tOPTIONAL.maybe >> tUNIQUE.maybe >> instantiableType).as(:arrayType)
|
|
178
|
+
end
|
|
179
|
+
rule(:assignmentStmt) do
|
|
180
|
+
(generalRef >> qualifier.repeat.as(:qualifier) >> op_decl >> expression >> op_delim).as(:assignmentStmt)
|
|
181
|
+
end
|
|
182
|
+
rule(:attributeDecl) do
|
|
183
|
+
(attributeId | redeclaredAttribute).as(:attributeDecl)
|
|
184
|
+
end
|
|
185
|
+
rule(:attributeId) { simpleId.as(:attributeId) }
|
|
186
|
+
rule(:attributeQualifier) do
|
|
187
|
+
(op_period >> attributeRef).as(:attributeQualifier)
|
|
188
|
+
end
|
|
189
|
+
rule(:attributeRef) { attributeId.as(:attributeRef) }
|
|
190
|
+
rule(:bagType) do
|
|
191
|
+
(tBAG >> boundSpec.maybe >> tOF >> instantiableType).as(:bagType)
|
|
192
|
+
end
|
|
193
|
+
rule(:binaryLiteral) do
|
|
194
|
+
cts((str("%") >> bit.repeat(1)).as(:str)).as(:binaryLiteral)
|
|
195
|
+
end
|
|
196
|
+
rule(:binaryType) { (tBINARY >> widthSpec.maybe).as(:binaryType) }
|
|
197
|
+
rule(:bit) { match["0-1"] }
|
|
198
|
+
rule(:booleanType) { tBOOLEAN.as(:booleanType) }
|
|
199
|
+
rule(:bound1) { numericExpression.as(:bound1) }
|
|
200
|
+
rule(:bound2) { numericExpression.as(:bound2) }
|
|
201
|
+
rule(:boundSpec) do
|
|
202
|
+
(op_leftbracket >> bound1 >> op_colon >> bound2 >> op_rightbracket).as(:boundSpec)
|
|
203
|
+
end
|
|
204
|
+
rule(:builtInConstant) do
|
|
205
|
+
(tCONST_E | tPI | tSELF | op_question_mark).as(:builtInConstant)
|
|
206
|
+
end
|
|
207
|
+
rule(:builtInFunction) do
|
|
208
|
+
(tABS | tACOS | tASIN | tATAN | tBLENGTH | tCOS | tEXISTS | tEXP | tFORMAT | tHIBOUND | tHIINDEX | tLENGTH |
|
|
209
|
+
tLOBOUND | tLOINDEX | tLOG2 | tLOG10 | tLOG | tNVL | tODD | tROLESOF | tSIN | tSIZEOF | tSQRT | tTAN |
|
|
210
|
+
tTYPEOF | tUSEDIN | tVALUE_IN | tVALUE_UNIQUE | tVALUE).as(:builtInFunction)
|
|
211
|
+
end
|
|
212
|
+
rule(:builtInProcedure) { (tINSERT | tREMOVE).as(:builtInProcedure) }
|
|
213
|
+
rule(:caseAction) do
|
|
214
|
+
((caseLabel >> (op_comma >> caseLabel).repeat).as(:listOf_caseLabel) >> op_colon >> stmt).as(:caseAction)
|
|
215
|
+
end
|
|
216
|
+
rule(:caseLabel) { expression.as(:caseLabel) }
|
|
217
|
+
rule(:caseStmt) do
|
|
218
|
+
(tCASE >> selector >> tOF >> caseAction.repeat.as(:caseAction) >> (tOTHERWISE >> op_colon >> stmt).maybe >> tEND_CASE >> op_delim).as(:caseStmt)
|
|
219
|
+
end
|
|
220
|
+
rule(:compoundStmt) do
|
|
221
|
+
(tBEGIN >> stmt.repeat(1).as(:stmt) >> tEND >> op_delim).as(:compoundStmt)
|
|
222
|
+
end
|
|
223
|
+
rule(:concreteTypes) do
|
|
224
|
+
(aggregationTypes | simpleTypes | typeRef).as(:concreteTypes)
|
|
225
|
+
end
|
|
226
|
+
rule(:constantBody) do
|
|
227
|
+
(constantId >> op_colon >> instantiableType >> op_decl >> expression >> op_delim).as(:constantBody)
|
|
228
|
+
end
|
|
229
|
+
rule(:constantDecl) do
|
|
230
|
+
(tCONSTANT >> constantBody.repeat(1).as(:constantBody) >> tEND_CONSTANT >> op_delim).as(:constantDecl)
|
|
231
|
+
end
|
|
232
|
+
rule(:constantFactor) do
|
|
233
|
+
(builtInConstant | constantRef).as(:constantFactor)
|
|
234
|
+
end
|
|
235
|
+
rule(:constantId) { simpleId.as(:constantId) }
|
|
236
|
+
rule(:constantRef) { constantId.as(:constantRef) }
|
|
237
|
+
rule(:constructedTypes) do
|
|
238
|
+
(enumerationType | selectType).as(:constructedTypes)
|
|
239
|
+
end
|
|
240
|
+
rule(:declaration) do
|
|
241
|
+
(entityDecl | functionDecl | procedureDecl | subtypeConstraintDecl | typeDecl).as(:declaration)
|
|
242
|
+
end
|
|
243
|
+
rule(:delim) { cts(str(";").as(:delim)) }
|
|
244
|
+
rule(:deriveClause) do
|
|
245
|
+
(tDERIVE >> derivedAttr.repeat(1).as(:derivedAttr)).as(:deriveClause)
|
|
246
|
+
end
|
|
247
|
+
rule(:derivedAttr) do
|
|
248
|
+
(attributeDecl >> op_colon >> parameterType >> op_decl >> expression >> op_delim).as(:derivedAttr)
|
|
249
|
+
end
|
|
250
|
+
rule(:digit) { match["0-9"] }
|
|
251
|
+
rule(:digits) { digit >> digit.repeat }
|
|
252
|
+
rule(:domainRule) do
|
|
253
|
+
((ruleLabelId >> op_colon).maybe >> expression).as(:domainRule)
|
|
254
|
+
end
|
|
255
|
+
rule(:element) do
|
|
256
|
+
(expression >> (op_colon >> repetition).maybe).as(:element)
|
|
257
|
+
end
|
|
258
|
+
rule(:embeddedRemark) do
|
|
259
|
+
(
|
|
260
|
+
# `(*)` is a 3-character empty embedded remark: the opener `(*`
|
|
261
|
+
# and closer `*)` share the `*`. Per strict ISO 10303-11 §7.1.6
|
|
262
|
+
# grammar the opener and closer are distinct tokens and cannot
|
|
263
|
+
# share characters, so `(*)` is technically invalid. We accept
|
|
264
|
+
# it for robustness (issue #126).
|
|
265
|
+
str("(*)") |
|
|
266
|
+
(str("(*") >> (str("*)").absent? >> (embeddedRemark | any)).repeat >> str("*)"))
|
|
267
|
+
).as(:embeddedRemark)
|
|
268
|
+
end
|
|
269
|
+
rule(:encodedCharacter) { octet >> octet >> octet >> octet }
|
|
270
|
+
rule(:encodedStringLiteral) do
|
|
271
|
+
cts((str('"') >> encodedCharacter.repeat(1) >> str('"')).as(:str)).as(:encodedStringLiteral)
|
|
272
|
+
end
|
|
273
|
+
rule(:entityBody) do
|
|
274
|
+
(explicitAttr.repeat.as(:explicitAttr) >> deriveClause.maybe >> inverseClause.maybe >> uniqueClause.maybe >> whereClause.maybe).as(:entityBody)
|
|
275
|
+
end
|
|
276
|
+
rule(:entityConstructor) do
|
|
277
|
+
(entityRef >> op_leftparen >> (expression >> (op_comma >> expression).repeat).as(:listOf_expression).maybe >> op_rightparen).as(:entityConstructor)
|
|
278
|
+
end
|
|
279
|
+
rule(:entityDecl) do
|
|
280
|
+
(entityHead >> entityBody >> tEND_ENTITY >> op_delim).as(:entityDecl)
|
|
281
|
+
end
|
|
282
|
+
rule(:entityHead) do
|
|
283
|
+
(tENTITY >> entityId >> subsuper >> op_delim).as(:entityHead)
|
|
284
|
+
end
|
|
285
|
+
rule(:entityId) { simpleId.as(:entityId) }
|
|
286
|
+
rule(:entityRef) { entityId.as(:entityRef) }
|
|
287
|
+
rule(:enumerationExtension) do
|
|
288
|
+
(tBASED_ON >> typeRef >> (tWITH >> enumerationItems).maybe).as(:enumerationExtension)
|
|
289
|
+
end
|
|
290
|
+
rule(:enumerationId) { simpleId.as(:enumerationId) }
|
|
291
|
+
rule(:enumerationItem) { enumerationId.as(:enumerationItem) }
|
|
292
|
+
rule(:enumerationItems) do
|
|
293
|
+
(op_leftparen >> (enumerationItem >> (op_comma >> enumerationItem).repeat).as(:listOf_enumerationItem) >> op_rightparen).as(:enumerationItems)
|
|
294
|
+
end
|
|
295
|
+
rule(:enumerationRef) { enumerationId.as(:enumerationRef) }
|
|
296
|
+
rule(:enumerationReference) do
|
|
297
|
+
((typeRef >> op_period).maybe >> enumerationRef).as(:enumerationReference)
|
|
298
|
+
end
|
|
299
|
+
rule(:enumerationType) do
|
|
300
|
+
(tEXTENSIBLE.maybe >> tENUMERATION >> ((tOF >> enumerationItems) | enumerationExtension).maybe).as(:enumerationType)
|
|
301
|
+
end
|
|
302
|
+
rule(:escapeStmt) { (tESCAPE >> op_delim).as(:escapeStmt) }
|
|
303
|
+
rule(:explicitAttr) do
|
|
304
|
+
((attributeDecl >> (op_comma >> attributeDecl).repeat).as(:listOf_attributeDecl) >> op_colon >>
|
|
305
|
+
tOPTIONAL.maybe >> parameterType >> op_delim).as(:explicitAttr)
|
|
306
|
+
end
|
|
307
|
+
rule(:expression) do
|
|
308
|
+
(simpleExpression >> (relOpExtended >> simpleExpression.as(:rhs)).maybe).as(:expression)
|
|
309
|
+
end
|
|
310
|
+
rule(:factor) do
|
|
311
|
+
(simpleFactor >> (op_double_asterisk >> simpleFactor.as(:rhs)).maybe).as(:factor)
|
|
312
|
+
end
|
|
313
|
+
rule(:formalParameter) do
|
|
314
|
+
((parameterId >> (op_comma >> parameterId).repeat).as(:listOf_parameterId) >> op_colon >> parameterType).as(:formalParameter)
|
|
315
|
+
end
|
|
316
|
+
rule(:functionCall) do
|
|
317
|
+
((builtInFunction | functionRef) >> actualParameterList.maybe).as(:functionCall)
|
|
318
|
+
end
|
|
319
|
+
rule(:functionDecl) do
|
|
320
|
+
(functionHead >> algorithmHead >> stmt.repeat(1).as(:stmt) >> tEND_FUNCTION >> op_delim).as(:functionDecl)
|
|
321
|
+
end
|
|
322
|
+
rule(:functionHead) do
|
|
323
|
+
(tFUNCTION >> functionId >>
|
|
324
|
+
(op_leftparen >> (formalParameter >> (op_delim >> formalParameter).repeat).as(:listOf_formalParameter) >> op_rightparen).maybe >>
|
|
325
|
+
op_colon >> parameterType >> op_delim.as(:op_delim2)).as(:functionHead)
|
|
326
|
+
end
|
|
327
|
+
rule(:functionId) { simpleId.as(:functionId) }
|
|
328
|
+
rule(:functionRef) { functionId.as(:functionRef) }
|
|
329
|
+
rule(:generalAggregationTypes) do
|
|
330
|
+
(generalArrayType | generalBagType | generalListType | generalSetType).as(:generalAggregationTypes)
|
|
331
|
+
end
|
|
332
|
+
rule(:generalArrayType) do
|
|
333
|
+
(tARRAY >> boundSpec.maybe >> tOF >> tOPTIONAL.maybe >> tUNIQUE.maybe >> parameterType).as(:generalArrayType)
|
|
334
|
+
end
|
|
335
|
+
rule(:generalBagType) do
|
|
336
|
+
(tBAG >> boundSpec.maybe >> tOF >> parameterType).as(:generalBagType)
|
|
337
|
+
end
|
|
338
|
+
rule(:generalizedTypes) do
|
|
339
|
+
(aggregateType | generalAggregationTypes | genericEntityType | genericType).as(:generalizedTypes)
|
|
340
|
+
end
|
|
341
|
+
rule(:generalListType) do
|
|
342
|
+
(tLIST >> boundSpec.maybe >> tOF >> tUNIQUE.maybe >> parameterType).as(:generalListType)
|
|
343
|
+
end
|
|
344
|
+
rule(:generalRef) { (parameterRef | variableId).as(:generalRef) }
|
|
345
|
+
rule(:generalSetType) do
|
|
346
|
+
(tSET >> boundSpec.maybe >> tOF >> parameterType).as(:generalSetType)
|
|
347
|
+
end
|
|
348
|
+
rule(:genericEntityType) do
|
|
349
|
+
(tGENERIC_ENTITY >> (op_colon >> typeLabel).maybe).as(:genericEntityType)
|
|
350
|
+
end
|
|
351
|
+
rule(:genericType) do
|
|
352
|
+
(tGENERIC >> (op_colon >> typeLabel).maybe).as(:genericType)
|
|
353
|
+
end
|
|
354
|
+
rule(:groupQualifier) do
|
|
355
|
+
(op_double_backslash >> entityRef).as(:groupQualifier)
|
|
356
|
+
end
|
|
357
|
+
rule(:hexDigit) { match["0-9a-fA-F"] }
|
|
358
|
+
rule(:ifStmtElseStatements) do
|
|
359
|
+
stmt.repeat(1).as(:stmt).as(:ifStmtElseStatements)
|
|
360
|
+
end
|
|
361
|
+
rule(:ifStmtStatements) do
|
|
362
|
+
stmt.repeat(1).as(:stmt).as(:ifStmtStatements)
|
|
363
|
+
end
|
|
364
|
+
rule(:ifStmt) do
|
|
365
|
+
(tIF >> logicalExpression >> tTHEN >> ifStmtStatements >> (tELSE >> ifStmtElseStatements).maybe >> tEND_IF >> op_delim).as(:ifStmt)
|
|
366
|
+
end
|
|
367
|
+
rule(:incrementControl) do
|
|
368
|
+
(variableId >> op_decl >> bound1 >> tTO >> bound2 >> (tBY >> increment).maybe).as(:incrementControl)
|
|
369
|
+
end
|
|
370
|
+
rule(:increment) { numericExpression.as(:increment) }
|
|
371
|
+
rule(:index1) { index.as(:index1) }
|
|
372
|
+
rule(:index2) { index.as(:index2) }
|
|
373
|
+
rule(:index) { numericExpression.as(:index) }
|
|
374
|
+
rule(:indexQualifier) do
|
|
375
|
+
(op_leftbracket >> index1 >> (op_colon >> index2).maybe >> op_rightbracket).as(:indexQualifier)
|
|
376
|
+
end
|
|
377
|
+
rule(:instantiableType) do
|
|
378
|
+
(concreteTypes | entityRef).as(:instantiableType)
|
|
379
|
+
end
|
|
380
|
+
rule(:integerLiteral) { cts(digits.as(:str)).as(:integerLiteral) }
|
|
381
|
+
rule(:integerType) { tINTEGER.as(:integerType) }
|
|
382
|
+
rule(:interfaceSpecification) do
|
|
383
|
+
(referenceClause | useClause).as(:interfaceSpecification)
|
|
384
|
+
end
|
|
385
|
+
rule(:intervalHigh) { simpleExpression.as(:intervalHigh) }
|
|
386
|
+
rule(:intervalItem) { simpleExpression.as(:intervalItem) }
|
|
387
|
+
rule(:intervalLow) { simpleExpression.as(:intervalLow) }
|
|
388
|
+
rule(:interval) do
|
|
389
|
+
(op_left_curly_brace >> intervalLow >> intervalOp >> intervalItem >> intervalOp.as(:intervalOp2) >>
|
|
390
|
+
intervalHigh >> op_right_curly_brace).as(:interval)
|
|
391
|
+
end
|
|
392
|
+
rule(:intervalOp) { (op_less_equal | op_less_than).as(:intervalOp) }
|
|
393
|
+
rule(:inverseAttr) do
|
|
394
|
+
(attributeDecl >> op_colon >> inverseAttrType >> tFOR >> (entityRef >> op_period).maybe >> attributeRef >> op_delim).as(:inverseAttr)
|
|
395
|
+
end
|
|
396
|
+
rule(:inverseAttrType) do
|
|
397
|
+
(((tSET | tBAG) >> boundSpec.maybe >> tOF).maybe >> entityRef).as(:inverseAttrType)
|
|
398
|
+
end
|
|
399
|
+
rule(:inverseClause) do
|
|
400
|
+
(tINVERSE >> inverseAttr.repeat(1).as(:inverseAttr)).as(:inverseClause)
|
|
401
|
+
end
|
|
402
|
+
rule(:letter) { match["a-zA-Z"] }
|
|
403
|
+
rule(:listType) do
|
|
404
|
+
(tLIST >> boundSpec.maybe >> tOF >> tUNIQUE.maybe >> instantiableType).as(:listType)
|
|
405
|
+
end
|
|
406
|
+
rule(:literal) do
|
|
407
|
+
(binaryLiteral | logicalLiteral | realLiteral | integerLiteral | stringLiteral).as(:literal)
|
|
408
|
+
end
|
|
409
|
+
rule(:localDecl) do
|
|
410
|
+
(tLOCAL >> localVariable.repeat(1).as(:localVariable) >> tEND_LOCAL >> op_delim).as(:localDecl)
|
|
411
|
+
end
|
|
412
|
+
rule(:localVariable) do
|
|
413
|
+
((variableId >> (op_comma >> variableId).repeat).as(:listOf_variableId) >>
|
|
414
|
+
op_colon >> parameterType >>
|
|
415
|
+
(op_decl >> expression).maybe >> op_delim).as(:localVariable)
|
|
416
|
+
end
|
|
417
|
+
rule(:logicalExpression) { expression.as(:logicalExpression) }
|
|
418
|
+
rule(:logicalLiteral) do
|
|
419
|
+
(tFALSE | tTRUE | tUNKNOWN).as(:logicalLiteral)
|
|
420
|
+
end
|
|
421
|
+
rule(:logicalType) { tLOGICAL.as(:logicalType) }
|
|
422
|
+
rule(:multiplicationLikeOp) do
|
|
423
|
+
(op_asterisk | op_slash | tDIV | tMOD | tAND | op_double_pipe).as(:multiplicationLikeOp)
|
|
424
|
+
end
|
|
425
|
+
rule(:namedTypeOrRename) do
|
|
426
|
+
(namedTypes >> (tAS >> (entityId | typeId)).maybe).as(:namedTypeOrRename)
|
|
427
|
+
end
|
|
428
|
+
rule(:namedTypes) { (entityRef | typeRef).as(:namedTypes) }
|
|
429
|
+
rule(:nullStmt) { op_delim.as(:nullStmt) }
|
|
430
|
+
rule(:numberType) { tNUMBER.as(:numberType) }
|
|
431
|
+
rule(:numericExpression) { simpleExpression.as(:numericExpression) }
|
|
432
|
+
rule(:octet) { hexDigit >> hexDigit }
|
|
433
|
+
rule(:oneOf) do
|
|
434
|
+
(tONEOF >> op_leftparen >> (supertypeExpression >>
|
|
435
|
+
(op_comma >> supertypeExpression).repeat).as(:listOf_supertypeExpression) >> op_rightparen).as(:oneOf)
|
|
436
|
+
end
|
|
437
|
+
rule(:op_asterisk) { cstr("*").as(:op_asterisk) }
|
|
438
|
+
rule(:op_colon) { cstr(":").as(:op_colon) }
|
|
439
|
+
rule(:op_colon_equals_colon) { cstr(":=:").as(:op_colon_equals_colon) }
|
|
440
|
+
rule(:op_colon_less_greater_colon) do
|
|
441
|
+
cstr(":<>:").as(:op_colon_less_greater_colon)
|
|
442
|
+
end
|
|
443
|
+
rule(:op_comma) { cstr(",").as(:op_comma) }
|
|
444
|
+
rule(:op_decl) { cstr(":=").as(:op_decl) }
|
|
445
|
+
rule(:op_delim) { cstr(";").as(:op_delim) }
|
|
446
|
+
rule(:op_double_asterisk) { cstr("**").as(:op_double_asterisk) }
|
|
447
|
+
rule(:op_double_backslash) { cstr("\\").as(:op_double_backslash) }
|
|
448
|
+
rule(:op_double_pipe) { cstr("||").as(:op_double_pipe) }
|
|
449
|
+
rule(:op_equals) { cstr("=").as(:op_equals) }
|
|
450
|
+
rule(:op_greater_equal) { cstr(">=").as(:op_greater_equal) }
|
|
451
|
+
rule(:op_greater_than) { cstr(">").as(:op_greater_than) }
|
|
452
|
+
rule(:op_leftbracket) { cstr("[").as(:op_leftbracket) }
|
|
453
|
+
rule(:op_left_curly_brace) { cstr("{").as(:op_left_curly_brace) }
|
|
454
|
+
rule(:op_leftparen) { cstr("(").as(:op_leftparen) }
|
|
455
|
+
rule(:op_less_equal) { cstr("<=").as(:op_less_equal) }
|
|
456
|
+
rule(:op_less_greater) { cstr("<>").as(:op_less_greater) }
|
|
457
|
+
rule(:op_less_than) { cstr("<").as(:op_less_than) }
|
|
458
|
+
rule(:op_minus) { cstr("-").as(:op_minus) }
|
|
459
|
+
rule(:op_period) { cstr(".").as(:op_period) }
|
|
460
|
+
rule(:op_pipe) { cstr("|").as(:op_pipe) }
|
|
461
|
+
rule(:op_plus) { cstr("+").as(:op_plus) }
|
|
462
|
+
rule(:op_query_begin) { cstr("<*").as(:op_query_begin) }
|
|
463
|
+
rule(:op_query_end) { cstr("*>").as(:op_query_end) }
|
|
464
|
+
rule(:op_question_mark) { cstr("?").as(:op_question_mark) }
|
|
465
|
+
rule(:op_rightbracket) { cstr("]").as(:op_rightbracket) }
|
|
466
|
+
rule(:op_right_curly_brace) { cstr("}").as(:op_right_curly_brace) }
|
|
467
|
+
rule(:op_rightparen) { cstr(")").as(:op_rightparen) }
|
|
468
|
+
rule(:op_slash) { cstr("/").as(:op_slash) }
|
|
469
|
+
rule(:parameter) { expression.as(:parameter) }
|
|
470
|
+
rule(:parameterId) { simpleId.as(:parameterId) }
|
|
471
|
+
rule(:parameterRef) { parameterId.as(:parameterRef) }
|
|
472
|
+
rule(:parameterType) do
|
|
473
|
+
(generalizedTypes | namedTypes | simpleTypes).as(:parameterType)
|
|
474
|
+
end
|
|
475
|
+
rule(:population) { entityRef.as(:population) }
|
|
476
|
+
rule(:precisionSpec) { numericExpression.as(:precisionSpec) }
|
|
477
|
+
rule(:primary) do
|
|
478
|
+
(literal | (qualifiableFactor >> qualifier.repeat.as(:qualifier))).as(:primary)
|
|
479
|
+
end
|
|
480
|
+
rule(:procedureCallStmt) do
|
|
481
|
+
((builtInProcedure | procedureRef) >> actualParameterList.maybe >> op_delim).as(:procedureCallStmt)
|
|
482
|
+
end
|
|
483
|
+
rule(:procedureDecl) do
|
|
484
|
+
(procedureHead >> algorithmHead >> stmt.repeat.as(:stmt) >> tEND_PROCEDURE >> op_delim).as(:procedureDecl)
|
|
485
|
+
end
|
|
486
|
+
rule(:procedureHeadParameter) do
|
|
487
|
+
(tVAR.maybe >> formalParameter).as(:procedureHeadParameter)
|
|
488
|
+
end
|
|
489
|
+
rule(:procedureHead) do
|
|
490
|
+
(tPROCEDURE >> procedureId >>
|
|
491
|
+
(op_leftparen >> (procedureHeadParameter >>
|
|
492
|
+
(op_delim >> procedureHeadParameter).repeat).as(:listOf_procedureHeadParameter) >> op_rightparen).maybe >> op_delim.as(:op_delim2)).as(:procedureHead)
|
|
493
|
+
end
|
|
494
|
+
rule(:procedureId) { simpleId.as(:procedureId) }
|
|
495
|
+
rule(:procedureRef) { procedureId.as(:procedureRef) }
|
|
496
|
+
rule(:qualifiableFactor) do
|
|
497
|
+
(functionCall | attributeRef | constantFactor | generalRef | population).as(:qualifiableFactor)
|
|
498
|
+
end
|
|
499
|
+
rule(:qualifiedAttribute) do
|
|
500
|
+
(tSELF >> groupQualifier >> attributeQualifier).as(:qualifiedAttribute)
|
|
501
|
+
end
|
|
502
|
+
rule(:qualifier) do
|
|
503
|
+
(attributeQualifier | groupQualifier | indexQualifier).as(:qualifier)
|
|
504
|
+
end
|
|
505
|
+
rule(:queryExpression) do
|
|
506
|
+
(tQUERY >> op_leftparen >> variableId >> op_query_begin >> aggregateSource >> op_pipe >> logicalExpression >> op_rightparen).as(:queryExpression)
|
|
507
|
+
end
|
|
508
|
+
rule(:realLiteral) do
|
|
509
|
+
cts((digits >> str(".") >> digits.maybe >> (match["eE"] >> sign.maybe >> digits).maybe).as(:str)).as(:realLiteral)
|
|
510
|
+
end
|
|
511
|
+
rule(:realType) do
|
|
512
|
+
(tREAL >> (op_leftparen >> precisionSpec >> op_rightparen).maybe).as(:realType)
|
|
513
|
+
end
|
|
514
|
+
rule(:redeclaredAttribute) do
|
|
515
|
+
(qualifiedAttribute >> (tRENAMED >> attributeId).maybe).as(:redeclaredAttribute)
|
|
516
|
+
end
|
|
517
|
+
rule(:referenceClause) do
|
|
518
|
+
(tREFERENCE >> tFROM >> schemaRef >>
|
|
519
|
+
(op_leftparen >> (resourceOrRename >> (op_comma >> resourceOrRename).repeat).as(:listOf_resourceOrRename) >> op_rightparen).maybe >> op_delim).as(:referenceClause)
|
|
520
|
+
end
|
|
521
|
+
rule(:referencedAttribute) do
|
|
522
|
+
(attributeRef | qualifiedAttribute).as(:referencedAttribute)
|
|
523
|
+
end
|
|
524
|
+
rule(:relOpExtended) { (relOp | tIN | tLIKE).as(:relOpExtended) }
|
|
525
|
+
rule(:relOp) do
|
|
526
|
+
(op_less_equal | op_greater_equal | op_less_greater | op_less_than | op_greater_than | op_equals |
|
|
527
|
+
op_colon_less_greater_colon | op_colon_equals_colon).as(:relOp)
|
|
528
|
+
end
|
|
529
|
+
rule(:renameId) do
|
|
530
|
+
(constantId | entityId | functionId | procedureId | typeId).as(:renameId)
|
|
531
|
+
end
|
|
532
|
+
rule(:repeatControl) do
|
|
533
|
+
(incrementControl.maybe >> whileControl.maybe >> untilControl.maybe).as(:repeatControl)
|
|
534
|
+
end
|
|
535
|
+
rule(:repeatStmt) do
|
|
536
|
+
(tREPEAT >> repeatControl >> op_delim >> stmt.repeat(1).as(:stmt) >> tEND_REPEAT >> op_delim.as(:op_delim2)).as(:repeatStmt)
|
|
537
|
+
end
|
|
538
|
+
rule(:repetition) { numericExpression.as(:repetition) }
|
|
539
|
+
rule(:resourceOrRename) do
|
|
540
|
+
(resourceRef >> (tAS >> renameId).maybe).as(:resourceOrRename)
|
|
541
|
+
end
|
|
542
|
+
rule(:resourceRef) do
|
|
543
|
+
(constantRef | entityRef | functionRef | procedureRef | typeRef).as(:resourceRef)
|
|
544
|
+
end
|
|
545
|
+
rule(:returnStmt) do
|
|
546
|
+
(tRETURN >> (op_leftparen >> expression >> op_rightparen).maybe >> op_delim).as(:returnStmt)
|
|
547
|
+
end
|
|
548
|
+
rule(:ruleDecl) do
|
|
549
|
+
(ruleHead >> algorithmHead >> stmt.repeat.as(:stmt) >> whereClause >> tEND_RULE >> op_delim).as(:ruleDecl)
|
|
550
|
+
end
|
|
551
|
+
rule(:ruleHead) do
|
|
552
|
+
(tRULE >> ruleId >> tFOR >> op_leftparen >>
|
|
553
|
+
(entityRef >> (op_comma >> entityRef).repeat).as(:listOf_entityRef) >> op_rightparen >> op_delim).as(:ruleHead)
|
|
554
|
+
end
|
|
555
|
+
rule(:ruleId) { simpleId.as(:ruleId) }
|
|
556
|
+
rule(:ruleLabelId) { simpleId.as(:ruleLabelId) }
|
|
557
|
+
rule(:ruleLabelRef) { ruleLabelId.as(:ruleLabelRef) }
|
|
558
|
+
rule(:ruleRef) { ruleId.as(:ruleRef) }
|
|
559
|
+
rule(:schemaBodyDeclaration) do
|
|
560
|
+
(declaration | ruleDecl).as(:schemaBodyDeclaration)
|
|
561
|
+
end
|
|
562
|
+
rule(:schemaBody) do
|
|
563
|
+
(interfaceSpecification.repeat.as(:interfaceSpecification) >> constantDecl.maybe >>
|
|
564
|
+
schemaBodyDeclaration.repeat.as(:schemaBodyDeclaration)).as(:schemaBody)
|
|
565
|
+
end
|
|
566
|
+
rule(:schemaDecl) do
|
|
567
|
+
(tSCHEMA >> schemaId >> schemaVersionId.maybe >> op_delim >> schemaBody >> tEND_SCHEMA >> op_delim.as(:op_delim2)).as(:schemaDecl)
|
|
568
|
+
end
|
|
569
|
+
rule(:schemaId) { simpleId.as(:schemaId) }
|
|
570
|
+
rule(:schemaRef) { schemaId.as(:schemaRef) }
|
|
571
|
+
rule(:schemaVersionId) { stringLiteral.as(:schemaVersionId) }
|
|
572
|
+
rule(:selectExtension) do
|
|
573
|
+
(tBASED_ON >> typeRef >> (tWITH >> selectList).maybe).as(:selectExtension)
|
|
574
|
+
end
|
|
575
|
+
rule(:selectList) do
|
|
576
|
+
(op_leftparen >> (namedTypes >> (op_comma >> namedTypes).repeat).as(:listOf_namedTypes) >> op_rightparen).as(:selectList)
|
|
577
|
+
end
|
|
578
|
+
rule(:selector) { expression.as(:selector) }
|
|
579
|
+
rule(:selectType) do
|
|
580
|
+
((tEXTENSIBLE >> tGENERIC_ENTITY.maybe).maybe >> tSELECT >> (selectList | selectExtension).maybe).as(:selectType)
|
|
581
|
+
end
|
|
582
|
+
rule(:setType) do
|
|
583
|
+
(tSET >> boundSpec.maybe >> tOF >> instantiableType).as(:setType)
|
|
584
|
+
end
|
|
585
|
+
rule(:sign) { match["+-"] }
|
|
586
|
+
rule(:simpleExpression) do
|
|
587
|
+
(term >> (addLikeOp.as(:operator) >> term).as(:item).repeat.as(:rhs)).as(:simpleExpression)
|
|
588
|
+
end
|
|
589
|
+
rule(:simpleFactor) do
|
|
590
|
+
(simpleFactorExpression | aggregateInitializer | entityConstructor | interval | queryExpression | stringLiteral |
|
|
591
|
+
simpleFactorUnaryExpression | enumerationReference).as(:simpleFactor)
|
|
592
|
+
end
|
|
593
|
+
rule(:simpleFactorExpression) do
|
|
594
|
+
((op_leftparen >> expression >> op_rightparen) | primary).as(:simpleFactorExpression)
|
|
595
|
+
end
|
|
596
|
+
rule(:simpleFactorUnaryExpression) do
|
|
597
|
+
(unaryOp >> simpleFactorExpression).as(:simpleFactorUnaryExpression)
|
|
598
|
+
end
|
|
599
|
+
rule(:simpleId) do
|
|
600
|
+
anyKeyword.absent? >> cts((match["a-zA-Z_"] >> match["a-zA-Z0-9_"].repeat).as(:str)).as(:simpleId)
|
|
601
|
+
end
|
|
602
|
+
rule(:simpleStringLiteral) do
|
|
603
|
+
cts((str("'") >> (str("'").absent? >> any).repeat >> str("'")).as(:str)).as(:simpleStringLiteral)
|
|
604
|
+
end
|
|
605
|
+
rule(:simpleTypes) do
|
|
606
|
+
(binaryType | booleanType | integerType | logicalType | numberType | realType | stringType).as(:simpleTypes)
|
|
607
|
+
end
|
|
608
|
+
rule(:skipStmt) { (tSKIP >> op_delim).as(:skipStmt) }
|
|
609
|
+
rule(:space) { match[" \r\n\t\f"] | embeddedRemark | tailRemark }
|
|
610
|
+
rule(:spaces) { space.repeat.as(:spaces) }
|
|
611
|
+
rule(:stmt) do
|
|
612
|
+
(aliasStmt | assignmentStmt | caseStmt | compoundStmt | escapeStmt | ifStmt |
|
|
613
|
+
nullStmt | procedureCallStmt | repeatStmt | returnStmt | skipStmt).as(:stmt)
|
|
614
|
+
end
|
|
615
|
+
rule(:stringLiteral) do
|
|
616
|
+
(simpleStringLiteral | encodedStringLiteral).as(:stringLiteral)
|
|
617
|
+
end
|
|
618
|
+
rule(:stringType) { (tSTRING >> widthSpec.maybe).as(:stringType) }
|
|
619
|
+
rule(:subsuper) do
|
|
620
|
+
(supertypeConstraint.maybe >> subtypeDeclaration.maybe).as(:subsuper)
|
|
621
|
+
end
|
|
622
|
+
rule(:subtypeConstraintBody) do
|
|
623
|
+
(abstractSupertype.maybe >> totalOver.maybe >> (supertypeExpression >> op_delim).maybe).as(:subtypeConstraintBody)
|
|
624
|
+
end
|
|
625
|
+
rule(:subtypeConstraintDecl) do
|
|
626
|
+
(subtypeConstraintHead >> subtypeConstraintBody >> tEND_SUBTYPE_CONSTRAINT >> op_delim).as(:subtypeConstraintDecl)
|
|
627
|
+
end
|
|
628
|
+
rule(:subtypeConstraintHead) do
|
|
629
|
+
(tSUBTYPE_CONSTRAINT >> subtypeConstraintId >> tFOR >> entityRef >> op_delim).as(:subtypeConstraintHead)
|
|
630
|
+
end
|
|
631
|
+
rule(:subtypeConstraintId) { simpleId.as(:subtypeConstraintId) }
|
|
632
|
+
rule(:subtypeConstraintRef) do
|
|
633
|
+
subtypeConstraintId.as(:subtypeConstraintRef)
|
|
634
|
+
end
|
|
635
|
+
rule(:subtypeConstraint) do
|
|
636
|
+
(tOF >> op_leftparen >> supertypeExpression >> op_rightparen).as(:subtypeConstraint)
|
|
637
|
+
end
|
|
638
|
+
rule(:subtypeDeclaration) do
|
|
639
|
+
(tSUBTYPE >> tOF >> op_leftparen >> entityRef >> (op_comma >> entityRef).repeat >> op_rightparen).as(:listOf_entityRef).as(:subtypeDeclaration)
|
|
640
|
+
end
|
|
641
|
+
rule(:supertypeConstraint) do
|
|
642
|
+
(abstractSupertypeDeclaration | abstractEntityDeclaration | supertypeRule).as(:supertypeConstraint)
|
|
643
|
+
end
|
|
644
|
+
rule(:supertypeExpression) do
|
|
645
|
+
(supertypeFactor >> (tANDOR.as(:operator) >> supertypeFactor).as(:item).repeat.as(:rhs)).as(:supertypeExpression)
|
|
646
|
+
end
|
|
647
|
+
rule(:supertypeFactor) do
|
|
648
|
+
(supertypeTerm >> (tAND.as(:operator) >> supertypeTerm).as(:item).repeat.as(:rhs)).as(:supertypeFactor)
|
|
649
|
+
end
|
|
650
|
+
rule(:supertypeRule) do
|
|
651
|
+
(tSUPERTYPE >> subtypeConstraint).as(:supertypeRule)
|
|
652
|
+
end
|
|
653
|
+
rule(:supertypeTerm) do
|
|
654
|
+
(entityRef | oneOf | (op_leftparen >> supertypeExpression >> op_rightparen)).as(:supertypeTerm)
|
|
655
|
+
end
|
|
656
|
+
rule(:syntax) do
|
|
657
|
+
(spaces.as(:spaces) >> schemaDecl.repeat(1).as(:schemaDecl) >> spaces.as(:trailer)).as(:syntax)
|
|
658
|
+
end
|
|
659
|
+
rule(:tailRemark) do
|
|
660
|
+
(str("--") >> (str("\n").absent? >> any).repeat >> str("\n").maybe).as(:tailRemark)
|
|
661
|
+
end
|
|
662
|
+
rule(:term) do
|
|
663
|
+
(factor >> (multiplicationLikeOp >> factor).as(:item).repeat.as(:rhs)).as(:term)
|
|
664
|
+
end
|
|
665
|
+
rule(:totalOver) do
|
|
666
|
+
(tTOTAL_OVER >> op_leftparen >> (entityRef >> (op_comma >> entityRef).repeat).as(:listOf_entityRef) >> op_rightparen >> op_delim).as(:totalOver)
|
|
667
|
+
end
|
|
668
|
+
rule(:typeDecl) do
|
|
669
|
+
(tTYPE >> typeId >> op_equals >> underlyingType >> op_delim >> whereClause.maybe >> tEND_TYPE >> op_delim.as(:op_delim2)).as(:typeDecl)
|
|
670
|
+
end
|
|
671
|
+
rule(:typeId) { simpleId.as(:typeId) }
|
|
672
|
+
rule(:typeLabelId) { simpleId.as(:typeLabelId) }
|
|
673
|
+
rule(:typeLabelRef) { typeLabelId.as(:typeLabelRef) }
|
|
674
|
+
rule(:typeLabel) { (typeLabelId | typeLabelRef).as(:typeLabel) }
|
|
675
|
+
rule(:typeRef) { typeId.as(:typeRef) }
|
|
676
|
+
rule(:unaryOp) { (op_plus | op_minus | tNOT).as(:unaryOp) }
|
|
677
|
+
rule(:underlyingType) do
|
|
678
|
+
(concreteTypes | constructedTypes).as(:underlyingType)
|
|
679
|
+
end
|
|
680
|
+
rule(:uniqueClause) do
|
|
681
|
+
(tUNIQUE >> (uniqueRule >> op_delim >> (uniqueRule >> op_delim.as(:op_delim2)).repeat).as(:listOf_uniqueRule)).as(:uniqueClause)
|
|
682
|
+
end
|
|
683
|
+
rule(:uniqueRule) do
|
|
684
|
+
((ruleLabelId >> op_colon).maybe >> (referencedAttribute >> (op_comma >> referencedAttribute).repeat).as(:listOf_referencedAttribute)).as(:uniqueRule)
|
|
685
|
+
end
|
|
686
|
+
rule(:untilControl) { (tUNTIL >> logicalExpression).as(:untilControl) }
|
|
687
|
+
rule(:useClause) do
|
|
688
|
+
(tUSE >> tFROM >> schemaRef >>
|
|
689
|
+
(op_leftparen >> (namedTypeOrRename >> (op_comma >>
|
|
690
|
+
namedTypeOrRename).repeat).as(:listOf_namedTypeOrRename) >> op_rightparen).maybe >> op_delim).as(:useClause)
|
|
691
|
+
end
|
|
692
|
+
rule(:variableId) { simpleId.as(:variableId) }
|
|
693
|
+
rule(:variableRef) { variableId.as(:variableRef) }
|
|
694
|
+
rule(:whereClause) do
|
|
695
|
+
(tWHERE >> (domainRule >> op_delim).repeat.as(:listOf_domainRule)).as(:whereClause)
|
|
696
|
+
end
|
|
697
|
+
rule(:whileControl) { (tWHILE >> logicalExpression).as(:whileControl) }
|
|
698
|
+
rule(:width) { numericExpression.as(:width) }
|
|
699
|
+
rule(:widthSpec) do
|
|
700
|
+
(op_leftparen >> width >> op_rightparen >> tFIXED.maybe).as(:widthSpec)
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
end
|
|
704
|
+
end
|
|
705
|
+
end
|