diff --git a/plugins/org.dslforge.xtext.generator/src/org/dslforge/xtext/generator/web/parser/GenGrammar.xtend b/plugins/org.dslforge.xtext.generator/src/org/dslforge/xtext/generator/web/parser/GenGrammar.xtend index 09eca80..47bd1b7 100644 --- a/plugins/org.dslforge.xtext.generator/src/org/dslforge/xtext/generator/web/parser/GenGrammar.xtend +++ b/plugins/org.dslforge.xtext.generator/src/org/dslforge/xtext/generator/web/parser/GenGrammar.xtend @@ -15,8 +15,11 @@ */ package org.dslforge.xtext.generator.web.parser +import java.util.Arrays +import java.util.HashSet import java.util.Iterator import java.util.List +import java.util.Set import java.util.regex.Matcher import java.util.regex.Pattern import org.dslforge.common.AbstractGenerator @@ -39,6 +42,7 @@ import org.eclipse.xtext.TerminalRule import org.eclipse.xtext.XtextFactory import org.eclipse.xtext.resource.SaveOptions import org.eclipse.xtext.resource.XtextResource +import org.eclipse.xtext.RuleCall class GenGrammar extends AbstractGenerator { @@ -91,7 +95,6 @@ class GenGrammar extends AbstractGenerator { val appendable = createAppendable() var grammarDefinition = grammar.eResource as XtextResource val rules = grammar.rules - // rename rules var List parserRules = GrammarUtil::allParserRules(grammar); for (ParserRule pr : parserRules) { @@ -101,23 +104,22 @@ class GenGrammar extends AbstractGenerator { for (EnumRule en : enumRules) { en.setName("rule_" + en.name.toFirstUpper) } - parserRules = GrammarUtil::allParserRules(grammar); for (ParserRule pr : parserRules) { - // rules on the client side are untyped + // rules are untyped println(pr) - pr.setType(null) - //remove semantic predicates + pr.setType(null) + //semantic predicates var List elements = GrammarUtil::containedAbstractElements(pr) for (AbstractElement e: elements) - e.predicated = false - // remove the actions (xtext-specific) + e.predicated = false + // actions val alternatives = pr.alternatives if (alternatives instanceof Group) { var List objs = (alternatives as Group).elements var Iterator i = objs.iterator(); while (i.hasNext()) { var o = i.next() - //remove actions + // actions if (o instanceof Action) { if (o.feature!=null) i.remove(); @@ -133,37 +135,39 @@ class GenGrammar extends AbstractGenerator { if (operator.equals("?=")) { a.setOperator("=") } - // cross references are not handled on the client side - // replace cross references in the form "reference=[Type|X]" to "reference=X" where X in {ID, STRING, FQN, ...} + // cross references if (terminal instanceof CrossReference) { var call = XtextFactory::eINSTANCE.createRuleCall var replacement = XtextFactory::eINSTANCE.createTerminalRule val allTerminalRules = GrammarUtil::allTerminalRules(grammar) for (TerminalRule t: allTerminalRules) { - if (t.name=="ID") - replacement=t + var x = terminal.terminal + if (x instanceof RuleCall) { + var rule = (x as RuleCall).rule + if (t.name==rule.name) + replacement=t + } + } call.setRule(replacement) a.setTerminal(call) } } - var text = grammarDefinition.serializer.serialize(pr, SaveOptions::defaultOptions) - // remove all the {Pattern.current=xxx} + var text = grammarDefinition.serializer.serialize(pr, SaveOptions::defaultOptions) + // {Pattern.current=xxx} val Pattern p = Pattern::compile("\\{(.+?)\\}") val Matcher m = p.matcher(text) while (m.find()) { val group = m.group if (!(group.substring(1, 2) == '\'')) text = text.replace(group, "") - } - // append EOF at the end of rule + } + //EOF if (rules.get(0).equals(pr)) text = text.substring(0, text.length - 1) + " EOF!" + ";" text = text.replaceAll("\"", "'") - appendable.newLine.append(text + "\n").newLine - + appendable.newLine.append(text + "\n") } - // Manage enumerations enumRules = GrammarUtil::allEnumRules(grammar); for (EnumRule en : enumRules) { @@ -181,9 +185,18 @@ class GenGrammar extends AbstractGenerator { } } builder.append(";") - appendable.newLine.append(builder + "\n").newLine + appendable.newLine.append(builder + "\n") + } + // Manage terminals + var terminalRules = GrammarUtil::allTerminalRules(grammar); + var Set covered = new HashSet(Arrays.asList("ID", "STRING", "COMMENT", "WS", "INT", "ML_COMMENT", "SL_COMMENT", "ANY_OTHER")); + for (TerminalRule terminal : terminalRules) { + if (!covered.contains(terminal.name)) { + var text = grammarDefinition.serializer.serialize(terminal, SaveOptions::defaultOptions) + text = text.replace("terminal ", ""); + appendable.newLine.append(text + "\n"); + } } - return appendable.content } @@ -196,8 +209,6 @@ class GenGrammar extends AbstractGenerator { WS: (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} ; - //NUMBER: INT ('.' INT)?; - INT: ('0'..'9')+; ''' @@ -205,4 +216,4 @@ class GenGrammar extends AbstractGenerator { val appendable = new StringAppendable(indentation, lineSeparator) return appendable } -} +} \ No newline at end of file