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

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

Automatic PDF Generation from .fo files now works

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