source: default/v2/trunk/de.ugoe.cs.swe.bnftools.ebnf/src/de/ugoe/cs/swe/bnftools/validation/EbnfValidator.xtend @ 65

Last change on this file since 65 was 65, checked in by hkaulbersch, 10 years ago

fixed imports

File size: 9.1 KB
Line 
1/*
2 * generated by Xtext
3 */
4package de.ugoe.cs.swe.bnftools.validation
5
6import de.ugoe.cs.swe.bnftools.ebnf.EbnfPackage
7import java.util.List
8import org.eclipse.xtext.validation.Check
9import de.ugoe.cs.swe.bnftools.ebnf.Rule
10import org.eclipse.xtext.nodemodel.util.NodeModelUtils
11import org.eclipse.xtext.nodemodel.ICompositeNode
12import de.ugoe.cs.swe.bnftools.ebnf.EtsiBnf
13import de.ugoe.cs.swe.bnftools.ebnf.RuleReference
14import de.ugoe.cs.swe.bnftools.ebnf.DefinitionList
15import de.ugoe.cs.swe.bnftools.ebnf.SingleDefinition
16import java.util.ArrayList
17
18//import java.util.HashMap
19//import java.util.Set
20//import java.util.HashSet
21//import org.eclipse.xtext.validation.Check
22/**
23 * Custom validation rules.
24 *
25 * see http://www.eclipse.org/Xtext/documentation.html#validation
26 */
27class EbnfValidator extends AbstractEbnfValidator {
28
29        public static final String ruleReferencedOneDescription = "The rule is only referenced by one other rule";
30        public static final String passthroughRuleDescription = "The rule is a passthrough rule";
31        public static final String unreferencedPassthroughRuleDescription = "The rule is an unreferenced passthrough rule";
32        public static final String unusedRuleDescription = "The rule is not referenced anywhere";
33        public static final String equalAlternativeDescription = "The rule contains equal alternatives";
34        public static final String duplicateRulesDescription = "The rule is a duplicate";
35
36        //public  static final String duplicateSubRulesDescription = "A part the of rule is a duplicate";
37        public static final String nonUniqueNameDescription = "The rule has the same Name as the Rule in Line ";
38
39        // ----------------------------------------------------------------------------------------------------
40        /* Checks if a rule is only referenced by one other Rule, e.g.:
41                 * a ::= b
42                 * b ::= "foo"
43                 */
44        @Check
45        def void checkReferencedOnlyOnce(Rule rule) {
46
47                if (EbnfAnalysisUtils.isTokenRule(rule))
48                        return;
49
50                var List<RuleReference> references = EbnfAnalysisUtils.findReferences(rule);
51
52                if (references.size() == 1 && rule.rulenumber != 1) {
53                        warning(ruleReferencedOneDescription, EbnfPackage$Literals::RULE__NAME, ruleReferencedOneDescription,
54                                rule.name);
55                }
56        }
57
58        // ----------------------------------------------------------------------------------------------------
59        /*Checks if a a rule has the same definition as another rule e.g.:
60         * a ::= "test"
61         * b ::= "test"
62         * (Problem: does not check if there is a permutation)
63         */
64        @Check
65        def void checkDuplicateRules(Rule rule) {
66
67                //load bnf
68                var EtsiBnf etsiBnf = rule.eContainer().eContainer() as EtsiBnf;
69
70                // find the rule in the parsetree
71                var ICompositeNode definitionList = NodeModelUtils.findActualNodeFor(rule.getDefinitionList());
72
73                //get the definitionList as  formatted string
74                var String rightHandSideText = definitionList.text.trim().replaceAll("[ \t\n\r]", "");
75
76                //get All Rules
77                var List<Rule> allRules = EbnfAnalysisUtils.getAllRules(etsiBnf);
78
79                // run through all Rules
80                                                for (currentRule : allRules) {
81                                                        if (currentRule != rule) {
82                                                                var ICompositeNode currentRuleDefinitionList = NodeModelUtils.findActualNodeFor(
83                                                                        currentRule.getDefinitionList());
84                                                                var String currentRuleRightHandSideText = currentRuleDefinitionList.text.trim().replaceAll("[ \t\n\r]",
85                                                                        "");
86                               
87                                                                if (currentRuleRightHandSideText.equals(rightHandSideText)) {
88                                                                        var String description = duplicateRulesDescription + " with rule \"" + currentRule.getName() +
89                                                                                "\" (Line " + NodeModelUtils.findActualNodeFor(currentRule).getStartLine() + ")";
90                                                                        warning(description, EbnfPackage$Literals::RULE__NAME);
91                                                                }
92                                                        }
93                                                }
94               
95//              //get all Single Definitions as Trimmed Strings
96//              var List<String> singleDefsAsString = new ArrayList<String>();
97//
98//              for (SingleDefinition s : (rule.definitionList).singleDefinition) {
99//                      singleDefsAsString.add(NodeModelUtils.findActualNodeFor(s).text.trim().replaceAll("[ \t\n\r]", ""));
100//              }
101//
102//              // for every rule get the single definitions as Strings
103//              var int j = 0;
104//              while (j<allRules.size) {
105//                      var currentRule=allRules.get(j);
106//                      if (currentRule != rule) {
107//                              var List<String> singleDefsAsString1 = new ArrayList<String>();
108//
109//                              for (SingleDefinition s : ( currentRule.definitionList).singleDefinition) {
110//                                      singleDefsAsString1.add(NodeModelUtils.findActualNodeFor(s).text.trim().replaceAll("[ \t\n\r]", ""));
111//                              }
112//
113//                              //for every String SingleDefinition find a corresponding ind the current rule
114//                              if (singleDefsAsString.size == singleDefsAsString1.size) {
115//                                      var List<String> singleDefsAsStringCpy = singleDefsAsString.clone;
116//                                      var boolean equal = true;
117//                                      while (equal) {
118//                                              var String momentaryString = singleDefsAsStringCpy.get(0);
119//                                              var int i = 0;
120//                                              var boolean found = false;
121//                                              while (i < singleDefsAsString1.size && !found) {
122//                                                      if (singleDefsAsString1.get(i).equals(momentaryString)) {
123//                                                              singleDefsAsStringCpy.remove(0);
124//                                                              singleDefsAsString1.remove(i);
125//                                                              found = true
126//                                                      }
127//                                                      i++;
128//                                              }
129//                                              if (!found) {
130//                                                      equal = false;
131//                                              }
132//                                              if (singleDefsAsStringCpy.empty) {
133//                                                      var String description = duplicateRulesDescription + " with rule \"" + currentRule.getName() +
134//                                                              "\" (Line " + NodeModelUtils.findActualNodeFor(currentRule).getStartLine() + ")";
135//                                                      warning(description, EbnfPackage$Literals::RULE__NAME)
136//                                              }
137//                                      }
138//                              }
139//
140//                      }
141//                      j++;
142//              }
143        }
144
145        // ----------------------------------------------------------------------------------------------------
146        /*Checks if a Rule got the same Name as another Rule, e.g.:
147         * a ::= "foo"
148         * a ::= "bar"
149         */
150        @Check
151        def void checkNameIsUnique(Rule rule) {
152                val EtsiBnf bnf = rule.eContainer.eContainer as EtsiBnf;
153                for (r : EbnfAnalysisUtils.getAllRules(bnf)) {
154                        if (rule.name.equals(r.name)) {
155                                if (!r.equals(rule)) {
156                                        error(nonUniqueNameDescription + NodeModelUtils.findActualNodeFor(r).startLine,
157                                                EbnfPackage$Literals::RULE__NAME)
158
159                                }
160                        }
161                }
162        }
163
164        // ----------------------------------------------------------------------------------------------------
165        /*Checks if a Rule, except for the #1 is not referenced, e.g.:
166         * a::= b
167         * b::="foo"
168         * c ::= "bar"
169         */
170        @Check
171        def void checkUnusedRule(Rule rule) {
172
173                var List<RuleReference> references = EbnfAnalysisUtils.findReferences(rule);
174
175                if ((references.size() == 0) && (rule.getRulenumber() != 1))
176                        warning(unusedRuleDescription, EbnfPackage$Literals::RULE__NAME, unusedRuleDescription, rule.name);
177        }
178
179        // ----------------------------------------------------------------------------------------------------
180        /*Checks if a rule got two equal alternatives, e.g.:
181         * a ::= b | "foo" | b
182         *(Problem:ignores whitespaces in literals)
183         */
184        @Check
185        def void checkEqualAlternative(Rule rule) {
186
187                var DefinitionList definitionList = rule.definitionList;
188
189                var List<SingleDefinition> singleDefinitions = definitionList.singleDefinition;
190
191                for (sDef1 : singleDefinitions) {
192                        for (sDef2 : singleDefinitions) {
193                                if (!sDef1.equals(sDef2)) {
194                                        var String d1 = NodeModelUtils.findActualNodeFor(sDef1).text.trim.replaceAll("[ \t\n\r]", "");
195                                        var String d2 = NodeModelUtils.findActualNodeFor(sDef2).text.trim.replaceAll("[ \t\n\r]", "");
196
197                                        if (d1.equals(d2))
198                                                warning(equalAlternativeDescription, EbnfPackage$Literals::RULE__NAME,
199                                                        equalAlternativeDescription, rule.name);
200                                }
201                        }
202                }
203
204        }
205
206        // ----------------------------------------------------------------------------------------------------
207        /* Checks if a rule gets just passed through, e.g.:
208         * a ::= b | "literal"
209         * b ::= c
210         * c ::= "foo.bar"
211         */
212        @Check
213        def void checkPassthroughRule(Rule rule) {
214
215                var List<RuleReference> references = EbnfAnalysisUtils.findReferences(rule);
216
217                if (EbnfAnalysisUtils.isPassthroughRule(rule) && rule.rulenumber != 1) {
218                        if (references.size() == 0) {
219                                warning(unreferencedPassthroughRuleDescription, EbnfPackage$Literals::RULE__NAME);
220                        } else {
221                                warning(passthroughRuleDescription, EbnfPackage$Literals::RULE__NAME, passthroughRuleDescription,
222                                        rule.name);
223                        }
224                }
225        }
226
227// ----------------------------------------------------------------------------------------------------
228/* Checks if a subrule is used more then once, e.g.:
229         * a ::= (a b) e
230         * b ::= (a b) d
231         *       _____
232         * (Not working, under construction)
233         */
234//      @Check
235//      def void checkSubruleDuplicates(EtsiBnf bnf){
236//              var HashMap<String, DuplicateEntry> dupesMap = new HashMap<String, DuplicateEntry>();
237//              var Set<String> taggedEntries = new HashSet<String>();
238//             
239//              var List<Rule> allRules = EbnfAnalysisUtils.getAllRules(bnf);
240//             
241//              for(rule: allRules){
242//                      var List<SingleDefinition> subrules = rule.definitionList.singleDefinition
243//                      for(subrule:subrules){
244//                              var String subruleText = NodeModelUtils.findActualNodeFor(subrule).text.trim.replaceAll("[ \t\n\r]", "");
245//                             
246//                      }
247//              }
248//      }
249}
Note: See TracBrowser for help on using the repository browser.