blob: 824fbac1e6eb1f9c9f5410c51bfc7261285d7ca3 [file] [log] [blame]
Ed Willinka55dbe42015-02-24 21:49:23 +00001/*******************************************************************************
Ed Willinkb79677d2017-05-23 19:50:22 +01002 * Copyright (c) 2015, 2017 Willink Transformations and others.
Ed Willinka55dbe42015-02-24 21:49:23 +00003 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * E.D.Willink - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.ocl.examples.build.xtend
12
13import com.google.inject.Inject
14import com.google.inject.Provider
15import com.google.inject.Singleton
16import java.util.List
17import org.eclipse.emf.common.util.URI
18import org.eclipse.emf.ecore.EClassifier
19import org.eclipse.emf.ecore.EObject
20import org.eclipse.emf.ecore.EPackage
21import org.eclipse.emf.ecore.resource.Resource
22import org.eclipse.jdt.annotation.NonNull
23import org.eclipse.ocl.xtext.base.utilities.AbstractGrammarResource
24import org.eclipse.xtext.AbstractElement
25import org.eclipse.xtext.AbstractMetamodelDeclaration
26import org.eclipse.xtext.AbstractRule
27import org.eclipse.xtext.Action
28import org.eclipse.xtext.Alternatives
29import org.eclipse.xtext.Assignment
30import org.eclipse.xtext.CharacterRange
31import org.eclipse.xtext.CrossReference
32import org.eclipse.xtext.Grammar
33import org.eclipse.xtext.Group
34import org.eclipse.xtext.Keyword
35import org.eclipse.xtext.NegatedToken
36import org.eclipse.xtext.ParserRule
37import org.eclipse.xtext.ReferencedMetamodel
38import org.eclipse.xtext.RuleCall
39import org.eclipse.xtext.TerminalRule
40import org.eclipse.xtext.TypeRef
41import org.eclipse.xtext.UntilToken
42import org.eclipse.xtext.Wildcard
43import org.eclipse.xtext.resource.XtextResourceSet
Adolfo SBHf23d81e2015-04-27 18:03:17 +010044import org.eclipse.xtext.EnumRule
45import org.eclipse.xtext.EnumLiteralDeclaration
46import org.eclipse.emf.ecore.EEnumLiteral
47import org.eclipse.xtext.UnorderedGroup
Ed Willinka55dbe42015-02-24 21:49:23 +000048
49/*
50 * Serialize a YYY.xtextbin grammar as an YYYGrammarResource.java class.
51 */
52public class GenerateGrammarXtend extends GenerateGrammar
53{
Ed Willink70051092015-12-23 19:11:07 +000054 /*@NonNull*/ protected override String generate(/*@NonNull*/ Resource grammarResource) {
Ed Willinka55dbe42015-02-24 21:49:23 +000055 '''
56 /*******************************************************************************
Ed Willinkb79677d2017-05-23 19:50:22 +010057 * Copyright (c) 2015, 2017 Willink Transformations and others.
Ed Willinka55dbe42015-02-24 21:49:23 +000058 * All rights reserved. This program and the accompanying materials
59 * are made available under the terms of the Eclipse Public License v1.0
60 * which accompanies this distribution, and is available at
61 * http://www.eclipse.org/legal/epl-v10.html
62 *
63 * Contributors:
64 * E.D.Willink - initial API and implementation
65 *******************************************************************************
66 * This code is 100% auto-generated
67 * from: «sourceFile»
68 * by: org.eclipse.ocl.examples.build.xtend.generateGrammar.xtend
69 *
70 * Do not edit it.
71 *******************************************************************************/
72 package «javaPackageName»;
73
74 import «List.getName()»;
75
76 import «URI.getName()»;
77 import «NonNull.getName()»;
78 import «EObject.getName()»;
79 import «AbstractGrammarResource.getName()»;
80 import «AbstractMetamodelDeclaration.getName()»;
81 import «AbstractRule.getName()»;
Adolfo SBHf23d81e2015-04-27 18:03:17 +010082 import «EnumRule.getName()»;
Ed Willinka55dbe42015-02-24 21:49:23 +000083 import «Grammar.getName()»;
84 import «ParserRule.getName()»;
85 import «ReferencedMetamodel.getName()»;
86 import «TerminalRule.getName()»;
87 import «XtextResourceSet.getName()»;
88
89 import «Inject.getName()»;
90 import «Provider.getName()»;
91 import «Singleton.getName()»;
92
93 /**
94 * «grammarFileStem»GrammarResource provides a programmatically initialized «languageName» Grammar model avoiding
95 * the speed limitations of the pre-Xtext 2.4 *.xmi models and the binary incompatibilities between differing *.xtextbin versions.
96 * <p>
97 * The grammar is immutable and is available as static INSTANCE and GRAMMAR fields.
98 */
Ed Willinkfacd3732015-04-29 22:15:38 +010099 @SuppressWarnings({"nls", "unused"})
Ed Willinka55dbe42015-02-24 21:49:23 +0000100 public class «grammarFileStem»GrammarResource extends AbstractGrammarResource
101 {
102 «FOR grammar : grammarResource.getContents()»
103 private static final @NonNull Grammar «emit(grammar as Grammar, grammar as Grammar)» = createGrammar(«emitValue((grammar as Grammar).getName())»);
104 «ENDFOR»
105
106 /**
107 * The shared immutable instance of the «languageName» Grammar resource.
108 */
109 public static final @NonNull «grammarFileStem»GrammarResource INSTANCE = new «grammarFileStem»GrammarResource();
110
111 /**
112 * The shared immutable instance of the «languageName» Grammar model.
113 */
Ed Willinkc86f5732016-04-19 09:42:58 +0100114 public static final @NonNull Grammar GRAMMAR = (Grammar)INSTANCE.getContents().get(0);
Ed Willinka55dbe42015-02-24 21:49:23 +0000115
116 /**
117 * The name of the language supported by this grammar.
118 */
119 public static final @NonNull String LANGUAGE_NAME = "«languageName»";
120
121 protected «grammarFileStem»GrammarResource() {
122 super(URI.createURI(LANGUAGE_NAME));
123 List<EObject> contents = getContents();
124 «FOR grammar : grammarResource.getContents()»
125 contents.add(«getGrammarPackageName(grammar as Grammar)».initGrammar());
126 «ENDFOR»
127 }
128
129 /*
130 * This class should be bound to org.eclipse.xtext.service.GrammarProvider.
131 */
132 @Singleton
133 public static class GrammarProvider extends org.eclipse.xtext.service.GrammarProvider
134 {
135 @Inject
136 public GrammarProvider(Provider<XtextResourceSet> resourceSetProvider) {
137 super(LANGUAGE_NAME, resourceSetProvider);
138 }
139
140 @Override
141 public Grammar getGrammar(Object requestor) {
142 return «grammarFileStem»GrammarResource.GRAMMAR;
143 }
144 }
145 «FOR grammar : grammarResource.getContents()»
146 «generateGrammarPackage(grammar as Grammar)»
147 «ENDFOR»
148 }
149 '''
150 }
151
Ed Willink70051092015-12-23 19:11:07 +0000152 /*@NonNull*/ protected def String generateEnumRules(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Iterable<EnumRule> eObjects) {
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100153 '''
154 «FOR eObject : eObjects»
155 private static final @NonNull EnumRule ER_«eObject.getName()» = createEnumRule(«emitValue(eObject.getName())», «emit(grammar, eObject.getType())»);
156 «ENDFOR»
157
158 private static void initEnumRules() {
159 «FOR eObject : eObjects»
160 «emit(grammar, eObject)».setAlternatives(«emit(grammar, eObject.alternatives)»);
161 «ENDFOR»
162 }
163
164 '''
165 }
166
Ed Willink70051092015-12-23 19:11:07 +0000167 /*@NonNull*/ protected def String generateGrammarPackage(/*@NonNull*/ Grammar grammar) {
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100168 var List<TerminalRule> terminalRules = getSortedAbstractRules(grammar, TerminalRule);
169 var List<EnumRule> enumRules = getSortedAbstractRules(grammar, EnumRule);
Ed Willinka55dbe42015-02-24 21:49:23 +0000170 '''
171
172 private static class «getGrammarPackageName(grammar)»
173 {
174 «generateReferencedMetamodels(grammar, getSortedReferencedMetamodels(grammar))»
175 «IF terminalRules.size() > 0»
176 «generateTerminalRules(grammar, terminalRules)»
177 «ENDIF»
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100178 «IF enumRules.size() > 0»
179 «generateEnumRules(grammar, enumRules)»
180 «ENDIF»
181 «generateParserRules(grammar, getSortedAbstractRules(grammar, ParserRule))»
182 «generateInitGrammar(grammar, terminalRules.size() > 0, enumRules.size() > 0)»
Ed Willinka55dbe42015-02-24 21:49:23 +0000183 }
184 '''
185 }
186
Ed Willink70051092015-12-23 19:11:07 +0000187 /*@NonNull*/ protected def String generateInitGrammar(/*@NonNull*/ Grammar grammar, boolean hasTerminals, boolean hasEnumRules) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000188 '''
189 private static @NonNull Grammar initGrammar() {
190 «IF hasTerminals»
191 initTerminalRules();
192 «ENDIF»
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100193 «IF hasEnumRules»
194 initEnumRules();
195 «ENDIF»
Ed Willinka55dbe42015-02-24 21:49:23 +0000196 initParserRules();
197 Grammar grammar = «emit(grammar, grammar)»;
198 «IF grammar.isDefinesHiddenTokens()»
199 grammar.setDefinesHiddenTokens(true);
200 «ENDIF»
201 «IF grammar.getMetamodelDeclarations().size() > 0»
202 {
203 List<AbstractMetamodelDeclaration> metamodelDeclarations = grammar.getMetamodelDeclarations();
204 «FOR element : grammar.getMetamodelDeclarations()»
205 metamodelDeclarations.add(«emit(grammar, element)»);
206 «ENDFOR»
207 }
208 «ENDIF»
209 «IF grammar.getRules().size() > 0»
210 {
211 List<AbstractRule> rules = grammar.getRules();
212 «FOR element : grammar.getRules()»
213 rules.add(«emit(grammar, element)»);
214 «ENDFOR»
215 }
216 «ENDIF»
217 «IF grammar.getUsedGrammars().size() > 0»
218 {
219 List<Grammar> usedGrammars = grammar.getUsedGrammars();
220 «FOR element : grammar.getUsedGrammars()»
221 usedGrammars.add(«emit(grammar, element)»);
222 «ENDFOR»
223 }
224 «ENDIF»
225 «IF grammar.getHiddenTokens().size() > 0»
226 {
227 List<AbstractRule> hiddenTokens = grammar.getHiddenTokens();
228 «FOR element : grammar.getHiddenTokens()»
229 hiddenTokens.add(«emit(grammar, element)»);
230 «ENDFOR»
231 }
232 «ENDIF»
233 return grammar;
234 }
235 '''
236 }
237
Ed Willink70051092015-12-23 19:11:07 +0000238 /*@NonNull*/ protected def String generateParserRules(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Iterable<ParserRule> eObjects) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000239 '''
240 «FOR eObject : eObjects»
241 private static final @NonNull ParserRule PR_«eObject.getName()» = createParserRule(«emitValue(eObject.getName())», «emit(grammar, eObject.getType())»);
242 «ENDFOR»
243
244 private static void initParserRules() {
245 «FOR eObject : eObjects»
246 «emit(grammar, eObject)».setAlternatives(«emit(grammar, eObject.alternatives)»);
247 «ENDFOR»
248 }
249
250 '''
251 }
252
Ed Willink70051092015-12-23 19:11:07 +0000253 /*@NonNull*/ protected def String generateReferencedMetamodels(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Iterable<ReferencedMetamodel> eObjects) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000254 '''
255 «FOR eObject : eObjects»
256 private static final @NonNull ReferencedMetamodel «emit(grammar, eObject)» = createReferencedMetamodel(«emit(grammar, eObject.getEPackage())», «emitValue(eObject.getAlias())»); // «eObject.getEPackage().getNsURI()»
257 «ENDFOR»
258
259 '''
260 }
261
Ed Willink70051092015-12-23 19:11:07 +0000262 /*@NonNull*/ protected def String generateTerminalRules(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Iterable<TerminalRule> eObjects) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000263 '''
264 «FOR eObject : eObjects»
265 private static final @NonNull TerminalRule TR_«eObject.getName()» = createTerminalRule(«emitValue(eObject.getName())», «emit(grammar, eObject.getType())»);
266 «ENDFOR»
267
268 private static void initTerminalRules() {
269 «FOR eObject : eObjects»
270 «IF eObject.isFragment()»
271 «emit(grammar, eObject)».setFragment(true);
272 «ENDIF»
273 «emit(grammar, eObject)».setAlternatives(«emit(grammar, eObject.alternatives)»);
274 «ENDFOR»
275 }
276
277 '''
278 }
279
280 /*
281 * Emit the eObject term inline within a grammar, either as a direct construction or as a name reference to a previous construction.
282 */
Ed Willink70051092015-12-23 19:11:07 +0000283 /*@NonNull*/ protected def String emit(/*@NonNull*/ Grammar grammar, /*@NonNull*/ EObject eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000284 switch eObject {
285 Action: return emitAction(grammar, eObject)
286 Alternatives: return emitAlternatives(grammar, eObject)
287 Assignment: return emitAssignment(grammar, eObject)
288 CharacterRange: return emitCharacterRange(grammar, eObject)
289 CrossReference: return emitCrossReference(grammar, eObject)
290 EClassifier: return emitEClassifierLiteral(eObject)
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100291 EPackage: return emitEPackageLiteral(eObject)
292 EEnumLiteral : return emitEEnumLiteral(eObject)
293 EnumRule: return emitEnumRuleLiteral(grammar, eObject)
294 EnumLiteralDeclaration: return emitEnumLiteralDeclaration(grammar, eObject)
Ed Willinka55dbe42015-02-24 21:49:23 +0000295 Grammar: return "G" + getGrammarPackageName(eObject)
296 Group: return emitGroup(grammar, eObject)
297 Keyword: return emitKeyword(eObject)
298 NegatedToken: return emitNegatedToken(grammar, eObject)
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100299 ParserRule: return emitParserRuleLiteral(grammar, eObject)
Ed Willinka55dbe42015-02-24 21:49:23 +0000300 ReferencedMetamodel: return emitReferencedMetamodelName(grammar, eObject)
301 RuleCall: return emitRuleCall(grammar, eObject)
302 TerminalRule: return emitTerminalRuleLiteral(grammar, eObject)
303 TypeRef: return emitTypeRef(grammar, eObject)
304 UntilToken: return emitUntilToken(grammar, eObject)
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100305 UnorderedGroup: return emitUnorderedGroup(grammar, eObject)
Ed Willinka55dbe42015-02-24 21:49:23 +0000306 Wildcard: return emitWildcard(grammar, eObject)
307 default: return emitSymbol(eObject.eClass(), eObject)
308 }
309 }
310
Ed Willink70051092015-12-23 19:11:07 +0000311 /*@NonNull*/ protected def String emitAction(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Action eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000312 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
313 '''createAction(«emitValue(eObject.getFeature())», «emitValue(eObject.getOperator())», «emit(grammar, eObject.getType())»)''')));
314 }
315
Ed Willink70051092015-12-23 19:11:07 +0000316 /*@NonNull*/ protected def String emitAlternatives(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Alternatives eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000317 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
318 '''createAlternatives(«FOR element : eObject.getElements() SEPARATOR ", "»«emit(grammar, element)»«ENDFOR»)''')));
319 }
320
Ed Willink70051092015-12-23 19:11:07 +0000321 /*@NonNull*/ protected def String emitAssignment(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Assignment eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000322 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
323 '''createAssignment(«emitValue(eObject.getFeature())», «emitValue(eObject.getOperator())», «emit(grammar, eObject.getTerminal())»)''')));
324 }
325
Ed Willink70051092015-12-23 19:11:07 +0000326 /*@NonNull*/ protected def String emitCharacterRange(/*@NonNull*/ Grammar grammar, /*@NonNull*/ CharacterRange eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000327 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
328 '''createCharacterRange(«emit(grammar, eObject.getLeft)», «emit(grammar, eObject.getRight)»)''')));
329 }
330
Ed Willink70051092015-12-23 19:11:07 +0000331 /*@NonNull*/ protected def String emitCrossReference(/*@NonNull*/ Grammar grammar, /*@NonNull*/ CrossReference eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000332 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
333 '''createCrossReference(«emit(grammar, eObject.getType())», «emit(grammar, eObject.getTerminal())»)''')));
334 }
335
Ed Willink70051092015-12-23 19:11:07 +0000336 /*@NonNull*/ protected def String emitEnumLiteralDeclaration(/*@NonNull*/ Grammar grammar, /*@NonNull*/ EnumLiteralDeclaration eObject) {
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100337 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
338 '''createEnumLiteral(«emit(grammar, eObject.literal)», «emit(grammar, eObject.enumLiteral)»)''')));
339
340
341 }
Ed Willink70051092015-12-23 19:11:07 +0000342 /*@NonNull*/ protected def String emitGroup(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Group eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000343 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
344 '''createGroup(«FOR element : eObject.getElements() SEPARATOR ", "»«emit(grammar, element)»«ENDFOR»)''')));
345 }
346
Ed Willink70051092015-12-23 19:11:07 +0000347 /*@NonNull*/ protected def String emitKeyword(/*@NonNull*/ Keyword eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000348 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
349 '''createKeyword(«emitValue(eObject.getValue())»)''')));
350 }
351
Ed Willink70051092015-12-23 19:11:07 +0000352 /*@NonNull*/ protected def String emitNegatedToken(/*@NonNull*/ Grammar grammar, /*@NonNull*/ NegatedToken eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000353 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
354 '''createNegatedToken(«emit(grammar, eObject.getTerminal())»)''')));
355 }
356
Ed Willink70051092015-12-23 19:11:07 +0000357 /*@NonNull*/ protected def String emitRuleCall(/*@NonNull*/ Grammar grammar, /*@NonNull*/ RuleCall eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000358 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
359 '''createRuleCall(«emit(grammar, eObject.getRule())»)''')));
360 }
361
Ed Willink70051092015-12-23 19:11:07 +0000362 /*@NonNull*/ protected def String emitTypeRef(/*@NonNull*/ Grammar grammar, /*@NonNull*/ TypeRef eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000363 return '''createTypeRef(«emit(grammar, eObject.getMetamodel())», «emit(grammar, eObject.getClassifier())»)''';
364 }
365
Ed Willink70051092015-12-23 19:11:07 +0000366 /*@NonNull*/ protected def String emitUnorderedGroup(/*@NonNull*/ Grammar grammar, /*@NonNull*/ UnorderedGroup eObject) {
Adolfo SBHf23d81e2015-04-27 18:03:17 +0100367 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
368 '''createUnorderedGroup(«FOR element : eObject.getElements() SEPARATOR ", "»«emit(grammar, element)»«ENDFOR»)''')));
369 }
370
Ed Willink70051092015-12-23 19:11:07 +0000371 /*@NonNull*/ protected def String emitUntilToken(/*@NonNull*/ Grammar grammar, /*@NonNull*/ UntilToken eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000372 return wrapCardinality(eObject, wrapFirstSetPredicated(eObject, wrapPredicated(eObject,
373 '''createUntilToken(«emit(grammar, eObject.getTerminal())»)''')));
374 }
375
Ed Willink70051092015-12-23 19:11:07 +0000376 /*@NonNull*/ protected def String emitWildcard(/*@NonNull*/ Grammar grammar, /*@NonNull*/ Wildcard eObject) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000377 return wrapCardinality(eObject, '''createWildcard()''');
378 }
379
Ed Willink70051092015-12-23 19:11:07 +0000380 /*@NonNull*/ protected def String wrapCardinality(/*@NonNull*/ AbstractElement eObject, String generatedElement) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000381 var String cardinality = eObject.getCardinality();
382 if (cardinality == null) {
383 return generatedElement;
384 }
385 else {
386 return '''setCardinality(«emitValue(cardinality)», «generatedElement»)''';
387 }
388 }
389
Ed Willink70051092015-12-23 19:11:07 +0000390 /*@NonNull*/ protected def String wrapFirstSetPredicated(/*@NonNull*/ AbstractElement eObject, String generatedElement) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000391 if (!eObject.isFirstSetPredicated()) {
392 return generatedElement;
393 }
394 else {
395 return '''setFirstSetPredicated(«generatedElement»)''';
396 }
397 }
398
Ed Willink70051092015-12-23 19:11:07 +0000399 /*@NonNull*/ protected def String wrapPredicated(/*@NonNull*/ AbstractElement eObject, String generatedElement) {
Ed Willinka55dbe42015-02-24 21:49:23 +0000400 if (!eObject.isPredicated()) {
401 return generatedElement;
402 }
403 else {
404 return '''setPredicated(«generatedElement»)''';
405 }
406 }
407}