blob: 6fc88eb85c7e0f65f26d83579fc21935f26ecee8 [file] [log] [blame]
package org.eclipse.gymnast.generators.ecore.cst;
import java.util.List;
import org.eclipse.gymnast.generator.core.ast.ListRule;
import org.eclipse.gymnast.generator.core.ast.Rule;
import org.eclipse.gymnast.generators.ecore.errors.Grammar2EcoreInvalidInput.EmptyTokenRule.MalformedListRule;
import org.eclipse.gymnast.runtime.core.parser.ParseContext;
/**
* @author Miguel Garcia, http://www.sts.tu-harburg.de/~mi.garcia/
*
*/
public class ListRuleCS extends RuleCS {
public String e1;
public String separator;
public String opt_e2;
public int lowerBound;
public String opt_FieldName1;
public String opt_FieldName2;
public ListRule lr;
public ListRuleCS(String name, String e1, String separator, String opt_e2,
int lowerBound, String opt_FieldName1, String opt_FieldName2,
RootCS c, ListRule lr) {
super(c);
this.name = name;
this.e1 = e1;
this.separator = separator;
this.opt_e2 = opt_e2;
this.lowerBound = lowerBound;
this.opt_FieldName1 = opt_FieldName1;
this.opt_FieldName2 = opt_FieldName2;
this.lr = lr;
}
/**
* Reject list rules: <br>
* (a) with a non-well-formed repeating item, <br>
* (b) with a 2nd repeating item (if specified) different from the first
* (thus, we assume repetition consists of only one kind of repeating item)
* <br>
* (c) containing a list as repeating item <br>
* (d) whose name shadows that of a built-in token <br>
*
* A list containing a non-constant separator is not rejected (e.g.,
* Emfatic.ast contains the token token qidSeparator : DOT | DOLLAR which is
* used as separator). Separators are stored by GenUnparseInhaleAndMM in
* their own list.
*
* A separator may be any kind of token or rule (except list) which is made
* up in its textual representation of a single uninterrupted sequence of
* printable characters.
*
*/
public boolean isMalformed(RootCS c) {
if (!opt_e2.equals("") && !c.namesMatch(e1, opt_e2)) {
return true;
}
if (c.findListRuleCSByName(e1) != null) {
return true;
}
if (isMalformedSeparator(separator)) {
return true;
}
if (c.isBuiltInToken(name)) {
return true;
}
return false;
}
private boolean isMalformedSeparator(String sepName) {
if (sepName.equals("")) {
return false;
}
if (c.canBeConsideredToken(sepName) || c.isSurroundedByQuotes(sepName)) {
return false;
}
RuleCS refedRuleIfAny = c.getRuleForNameIfAny(e1);
if (refedRuleIfAny instanceof TokenRuleCS) {
return false;
}
// ListRuleCS is ruled out
if (refedRuleIfAny instanceof ListRuleCS) {
return true;
}
if (refedRuleIfAny != null) {
if (refedRuleIfAny instanceof AltRuleCS) {
return isMalformedSeparator((AltRuleCS) refedRuleIfAny);
}
if (refedRuleIfAny instanceof SeqRuleCS) {
return isMalformedSeparator((SeqRuleCS) refedRuleIfAny);
}
}
return false;
}
private boolean isMalformedSeparator(SeqRuleCS srCS) {
if (srCS.seqexprs.size() > 1) {
return true;
}
if (isMalformedSeparator(srCS.seqexprs.get(0).value)) {
return true;
}
return false;
}
private boolean isMalformedSeparator(AltRuleCS refedRule) {
List<String> terminals = refedRule.explodeTerminalAlternatives();
boolean res = containsCompositeSeqRule(terminals);
return res;
}
/**
* A separator may be any kind of token or rule (except list) which is made
* up in its textual representation of a single uninterrupted sequence of
* printable characters.
*
*
*/
private boolean containsCompositeSeqRule(List<String> terminals) {
for (String t : terminals) {
if (!c.canBeConsideredToken(t)) {
SeqRuleCS refedSeqRule = c.findSeqRuleCSByName(t);
if (refedSeqRule != null) {
/*
* check if it consist of primitive constituents only, i.e.
* its textual representation is a single word.
*/
if (refedSeqRule.seqexprs.size() > 1) {
return true;
}
if (isMalformedSeparator(refedSeqRule.seqexprs.get(0).value)) {
return true;
}
}
}
}
return false;
}
public String unparseConstantSeparator() {
assert !isMalformed(c);
if (c.isSurroundedByQuotes(separator)) {
return c.unquote(separator);
}
if (c.isBuiltInToken(separator)) {
return c.getValueOfBuiltInToken(separator);
}
if (separator != null && separator.equals("")) {
return " ";
}
/*
* e.g. qidSeparator with alternativas DOT and STAR. See comment for
* isMalformed() in ListRuleCS
*/
return null;
}
public String getPreferredItemName() {
String res = opt_FieldName1.equals("") ? e1 : opt_FieldName1;
return res;
}
@Override
public String toString() {
String out_e1 = opt_FieldName1.equals("") ? e1 : opt_FieldName1 + "="
+ e1;
String out_e2 = opt_FieldName2.equals("") ? opt_e2 : opt_FieldName2
+ "=" + opt_e2;
System.out.println("list " + name + " : " + out_e1 + " " + separator
+ " " + out_e2 + " " + lowerBound);
return name;
}
public boolean hasConstantSeparator() {
if (separator.equals("") || c.isBuiltInToken(separator)
|| c.isSurroundedByQuotes(separator)) {
return true;
}
return false;
}
public SeqExprKind getKindOfItem() {
SeqExprCS temp = new SeqExprCS(false, e1, e1, lowerBound, c);
temp.value = e1;
SeqExprKind res = temp.getKind();
return res;
}
@Override
public Rule getRule() {
return lr;
}
public void addParseMessages(ParseContext parseContext) {
// TODO make finer distionction reflecting those in isMalformed()
MalformedListRule parseMessage = new MalformedListRule(this);
parseContext.addParseMessage(parseMessage);
}
@Override
public final boolean canBeRegardedAsBoolean() {
return false;
}
}