View Javadoc
1   /*
2    * Copyright 2013-2022 Medical Information Systems Research Group (https://medical.zcu.cz),
3    * Department of Computer Science and Engineering, University of West Bohemia.
4    * Address: Univerzitni 8, 306 14 Plzen, Czech Republic.
5    *
6    * This file is part of Sparkle project.
7    *
8    * Sparkle is free software: you can redistribute it and/or modify
9    * it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License.
11   *
12   * Sparkle is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with Sparkle. If not, see <http://www.gnu.org/licenses/>.
19   */
20  package cz.zcu.mre.sparkle.tools.sparqlValidation;
21  
22  import cz.zcu.mre.sparkle.tools.SparqlParser;
23  import org.antlr.v4.runtime.*;
24  import org.antlr.v4.runtime.atn.ATNState;
25  import org.antlr.v4.runtime.atn.RuleTransition;
26  import org.antlr.v4.runtime.atn.Transition;
27  import org.antlr.v4.runtime.misc.IntervalSet;
28  import org.antlr.v4.runtime.misc.ParseCancellationException;
29  import java.util.*;
30  
31  /**
32   * SPARQL Syntax Error listener. Zachytava a reportuje chyby pri parsovani
33   * dotazu. Chyby jsou ukladany do seznamu, aby je bylo mozne zobrazit.
34   *
35   * @author Klara Hlavacova
36   * @author Petr Vcelak (vcelak@kiv.zcu.cz)
37   */
38  public class SparqlValidationSyntaxErrorListener
39          extends BaseErrorListener {
40  
41      private final List<SyntaxError> syntaxErrorList;
42  
43      public SparqlValidationSyntaxErrorListener() {
44          syntaxErrorList = new ArrayList<>();
45      }
46  
47      @Override
48      public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
49              String msg, RecognitionException e) throws ParseCancellationException {
50  
51          if (e == null) {
52              e = new InlineRecognitionException(msg, recognizer, ((Parser) recognizer).getInputStream(),
53                      ((Parser) recognizer).getContext(), (Token) offendingSymbol);
54          }
55  
56          /* System.out.println("ERROR ON LINE " +line + "; " + charPositionInLine + "; "
57                             +  ((Token)offendingSymbol).getText()
58                             + "; NEXT:" +  offendingSymbol);*/
59  //        ATNState atnState = recognizer.getATN().states.get(recognizer.getState());
60          /* System.out.println(e.getRecognizer().getState());
61          System.out.println(recognizer.getRuleNames()[atnState.ruleIndex]);
62          System.out.println(e.getCtx());
63  
64          for (Integer et : e.getExpectedTokens().toList()) {
65              System.out.print(recognizer.getVocabulary().getDisplayName(et) + ", ");
66          }*/
67  
68          SyntaxError error = new SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
69  
70  //        Set<ATNState> seen = new HashSet<>();
71  //        Set<String> nextRules = nextRulesOrTokens((Parser) recognizer, atnState, seen, error);
72          /* System.out.print("\n==");
73          for (String et : nextRules) {
74              System.out.print(et + ", ");
75          }
76          System.out.println("==");*/
77  
78          if (!syntaxErrorList.contains(error)) {
79              syntaxErrorList.add(error);
80          }
81      }
82  
83      /**
84       * Vrati seznam pravidel a tokenu, ktere mohou nasledovat
85       *
86       * @param recognizer recognizer
87       * @param state stav
88       * @param seen pomocna mnozina stavu
89       * @param error prepravka s informacemi o chybe
90       *
91       * @return seznam pravidel a tokenu, ktere mohou nasledovat
92       */
93      public Set<String> nextRulesOrTokens(Parser recognizer, ATNState state, Set<ATNState> seen, SyntaxError error) {
94          Set<String> result = new LinkedHashSet<>();
95  
96          if (!seen.add(state)) {
97              return result;
98          }
99  
100         for (Transition t : state.getTransitions()) {
101             if (t instanceof RuleTransition) {
102                 result.add(recognizer.getRuleNames()[((RuleTransition) t).ruleIndex]);
103             } else if (t.isEpsilon()) {
104                 result.addAll(nextRulesOrTokens(recognizer, t.target, seen, error));
105             } else {
106                 IntervalSet label = t.label();
107                 if (label != null) {
108                     if (label.toList().contains((Integer) SparqlParser.AS)) {
109                         error.getExpectedTokens().addAll(label);
110                     }
111                     result.add(label.toString(recognizer.getVocabulary()));
112                 }
113             }
114         }
115         return result;
116     }
117 
118     public List<SyntaxError> getSyntaxErrorList() {
119         return syntaxErrorList;
120     }
121 
122     static class InlineRecognitionException
123             extends RecognitionException {
124 
125         InlineRecognitionException(String message, Recognizer<?, ?> recognizer,
126                 IntStream input, ParserRuleContext ctx, Token offendingToken) {
127 
128             super(message, recognizer, input, ctx);
129             this.setOffendingToken(offendingToken);
130         }
131     }
132 
133 }