/** * generated by Xtext */ package de.ugoe.cs.swe.bnftools.validation; import com.google.common.base.Objects; import de.ugoe.cs.swe.bnftools.ebnf.DefinitionList; import de.ugoe.cs.swe.bnftools.ebnf.EbnfPackage; import de.ugoe.cs.swe.bnftools.ebnf.EtsiBnf; import de.ugoe.cs.swe.bnftools.ebnf.Rule; import de.ugoe.cs.swe.bnftools.ebnf.RuleReference; import de.ugoe.cs.swe.bnftools.ebnf.SingleDefinition; import de.ugoe.cs.swe.bnftools.validation.AbstractEbnfValidator; import de.ugoe.cs.swe.bnftools.validation.EbnfAnalysisUtils; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.nodemodel.ICompositeNode; import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.eclipse.xtext.validation.Check; /** * Custom validation rules. * * see http://www.eclipse.org/Xtext/documentation.html#validation */ @SuppressWarnings("all") public class EbnfValidator extends AbstractEbnfValidator { private final static String ruleReferencedOneDescription = "The rule is only referenced by one other rule"; private final static String passthroughRuleDescription = "The rule is a passthrough rule"; private final static String unreferencedPassthroughRuleDescription = "The rule is an unreferenced passthrough rule"; private final static String unusedRuleDescription = "The rule is not referenced anywhere"; private final static String equalAlternativeDescription = "The rule contains equal alternatives"; private final static String duplicateRulesDescription = "The rule is a duplicate"; private final static String nonUniqueNameDescription = "The rule has the same Name as the Rule in Line "; /** * Checks if a rule is only referenced by one other Rule, e.g.: * a ::= b * b ::= "foo" */ @Check public void checkReferencedOnlyOnce(final Rule rule) { boolean _isTokenRule = EbnfAnalysisUtils.isTokenRule(rule); if (_isTokenRule) { return; } List references = EbnfAnalysisUtils.findReferences(rule); boolean _and = false; int _size = references.size(); boolean _equals = (_size == 1); if (!_equals) { _and = false; } else { int _rulenumber = rule.getRulenumber(); boolean _notEquals = (_rulenumber != 1); _and = _notEquals; } if (_and) { this.warning(EbnfValidator.ruleReferencedOneDescription, EbnfPackage.Literals.RULE__NAME); } } /** * Checks if a a rule has the same definition as another rule e.g.: * a ::= "test" * b ::= "test" * (Problem: does not check if there is a permutation) */ @Check public void checkDuplicateRules(final Rule rule) { EObject _eContainer = rule.eContainer(); EObject _eContainer_1 = _eContainer.eContainer(); EtsiBnf etsiBnf = ((EtsiBnf) _eContainer_1); DefinitionList _definitionList = rule.getDefinitionList(); ICompositeNode definitionList = NodeModelUtils.findActualNodeFor(_definitionList); String _text = definitionList.getText(); String _trim = _text.trim(); String rightHandSideText = _trim.replaceAll("[ \t\n\r]", ""); List allRules = EbnfAnalysisUtils.getAllRules(etsiBnf); for (final Rule currentRule : allRules) { boolean _notEquals = (!Objects.equal(currentRule, rule)); if (_notEquals) { DefinitionList _definitionList_1 = currentRule.getDefinitionList(); ICompositeNode currentRuleDefinitionList = NodeModelUtils.findActualNodeFor(_definitionList_1); String _text_1 = currentRuleDefinitionList.getText(); String _trim_1 = _text_1.trim(); String currentRuleRightHandSideText = _trim_1.replaceAll("[ \t\n\r]", ""); boolean _equals = currentRuleRightHandSideText.equals(rightHandSideText); if (_equals) { String _name = currentRule.getName(); String _plus = ((EbnfValidator.duplicateRulesDescription + " with rule \"") + _name); String _plus_1 = (_plus + "\" (Line "); ICompositeNode _findActualNodeFor = NodeModelUtils.findActualNodeFor(currentRule); int _startLine = _findActualNodeFor.getStartLine(); String _plus_2 = (_plus_1 + Integer.valueOf(_startLine)); String description = (_plus_2 + ")"); this.warning(description, EbnfPackage.Literals.RULE__NAME); } } } } /** * Checks if a Rule got the same Name as another Rule, e.g.: * a ::= "foo" * a ::= "bar" */ @Check public void checkNameIsUnique(final Rule rule) { EObject _eContainer = rule.eContainer(); EObject _eContainer_1 = _eContainer.eContainer(); final EtsiBnf bnf = ((EtsiBnf) _eContainer_1); List _allRules = EbnfAnalysisUtils.getAllRules(bnf); for (final Rule r : _allRules) { String _name = rule.getName(); String _name_1 = r.getName(); boolean _equals = _name.equals(_name_1); if (_equals) { boolean _equals_1 = r.equals(rule); boolean _not = (!_equals_1); if (_not) { ICompositeNode _findActualNodeFor = NodeModelUtils.findActualNodeFor(r); int _startLine = _findActualNodeFor.getStartLine(); String _plus = (EbnfValidator.nonUniqueNameDescription + Integer.valueOf(_startLine)); this.error(_plus, EbnfPackage.Literals.RULE__NAME); } } } } /** * Checks if a Rule, except for the #1 is not referenced, e.g.: * a::= b * b::="foo" * c ::= "bar" */ @Check public void checkUnusedRule(final Rule rule) { List references = EbnfAnalysisUtils.findReferences(rule); boolean _and = false; int _size = references.size(); boolean _equals = (_size == 0); if (!_equals) { _and = false; } else { int _rulenumber = rule.getRulenumber(); boolean _notEquals = (_rulenumber != 1); _and = _notEquals; } if (_and) { this.warning(EbnfValidator.unusedRuleDescription, EbnfPackage.Literals.RULE__NAME); } } /** * Checks if a rule got two equal alternatives, e.g.: * a ::= b | "foo" | b * (Problem:ignores whitespaces in literals) */ @Check public void checkEqualAlternative(final Rule rule) { DefinitionList definitionList = rule.getDefinitionList(); List singleDefinitions = definitionList.getSingleDefinition(); for (final SingleDefinition sDef1 : singleDefinitions) { for (final SingleDefinition sDef2 : singleDefinitions) { boolean _equals = sDef1.equals(sDef2); boolean _not = (!_equals); if (_not) { ICompositeNode _findActualNodeFor = NodeModelUtils.findActualNodeFor(sDef1); String _text = _findActualNodeFor.getText(); String _trim = _text.trim(); String d1 = _trim.replaceAll("[ \t\n\r]", ""); ICompositeNode _findActualNodeFor_1 = NodeModelUtils.findActualNodeFor(sDef2); String _text_1 = _findActualNodeFor_1.getText(); String _trim_1 = _text_1.trim(); String d2 = _trim_1.replaceAll("[ \t\n\r]", ""); boolean _equals_1 = d1.equals(d2); if (_equals_1) { this.warning(EbnfValidator.equalAlternativeDescription, EbnfPackage.Literals.RULE__NAME, EbnfValidator.equalAlternativeDescription); } } } } } /** * Checks if a rule gets just passed through, e.g.: * a ::= b | "literal" * b ::= c * c ::= "foo.bar" */ @Check public void checkPassthroughRule(final Rule rule) { List references = EbnfAnalysisUtils.findReferences(rule); boolean _isPassthroughRule = EbnfAnalysisUtils.isPassthroughRule(rule); if (_isPassthroughRule) { int _size = references.size(); boolean _equals = (_size == 0); if (_equals) { this.warning(EbnfValidator.unreferencedPassthroughRuleDescription, EbnfPackage.Literals.RULE__NAME); } else { this.warning(EbnfValidator.passthroughRuleDescription, EbnfPackage.Literals.RULE__NAME, EbnfValidator.passthroughRuleDescription); } } } }