|
|
@@ -1,16 +1,17 @@
|
|
|
package net.ranides.assira.grammar.impl;
|
|
|
|
|
|
import lombok.Data;
|
|
|
-import net.ranides.assira.collection.lists.ListUtils;
|
|
|
import net.ranides.assira.collection.maps.CrossMap;
|
|
|
import net.ranides.assira.collection.maps.OpenCrossMap;
|
|
|
import net.ranides.assira.collection.sets.OpenSet;
|
|
|
+import net.ranides.assira.generic.Ref;
|
|
|
import net.ranides.assira.grammar.G4ErrorHandler;
|
|
|
import net.ranides.assira.grammar.G4Exception;
|
|
|
import net.ranides.assira.grammar.G4Node;
|
|
|
import net.ranides.assira.grammar.G4Parser;
|
|
|
-import net.ranides.assira.generic.Ref;
|
|
|
import net.ranides.assira.grammar.G4ParserCoverage;
|
|
|
+import net.ranides.assira.grammar.impl.CoverageSupport.SimpleBranchCoverage;
|
|
|
+import net.ranides.assira.grammar.impl.CoverageSupport.SimpleRuleCoverage;
|
|
|
import net.ranides.assira.text.StringUtils;
|
|
|
import org.antlr.runtime.ANTLRStringStream;
|
|
|
import org.antlr.runtime.RecognitionException;
|
|
|
@@ -38,10 +39,12 @@ import org.antlr.v4.tool.ast.AltAST;
|
|
|
import org.antlr.v4.tool.ast.GrammarAST;
|
|
|
import org.antlr.v4.tool.ast.GrammarRootAST;
|
|
|
|
|
|
+import java.util.Collection;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.NoSuchElementException;
|
|
|
import java.util.Set;
|
|
|
+import java.util.TreeMap;
|
|
|
|
|
|
public class G4ParserInterpreter implements G4Parser {
|
|
|
|
|
|
@@ -233,9 +236,7 @@ public class G4ParserInterpreter implements G4Parser {
|
|
|
|
|
|
@Override
|
|
|
public G4ParserCoverage rules() {
|
|
|
- Vocabulary v = grammar.getVocabulary();
|
|
|
- List<String> tokens = ListUtils.produce(v.getMaxTokenType() + 1, v::getSymbolicName);
|
|
|
- throw new UnsupportedOperationException("TODO"); // @TODO implement that
|
|
|
+ return new MyCoverage();
|
|
|
}
|
|
|
|
|
|
private class MyRoot extends RootAbstract {
|
|
|
@@ -295,6 +296,99 @@ public class G4ParserInterpreter implements G4Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private class MyCoverage extends G4ParserCoverage {
|
|
|
+
|
|
|
+ private final Map<String, RuleCoverage> rules;
|
|
|
+ private final Map<String, BranchCoverage> branches;
|
|
|
+ private final Map<String, String> aliases;
|
|
|
+
|
|
|
+ public MyCoverage() {
|
|
|
+ // @todo fix coverage: borderSize#borderSize2 <= borderSizeComponent
|
|
|
+ // this alternative links to only one grammar rule, granted, BUT:
|
|
|
+ // this rule is repeated, it is not "simple alias". we should ignore that.
|
|
|
+
|
|
|
+ rules = new TreeMap<>();
|
|
|
+ branches = new TreeMap<>();
|
|
|
+ aliases = new TreeMap<>();
|
|
|
+
|
|
|
+ Vocabulary v = grammar.getVocabulary();
|
|
|
+
|
|
|
+ for(int i=1, n = v.getMaxTokenType(); i<=n; i++) {
|
|
|
+ String token = v.getSymbolicName(i);
|
|
|
+ rules.put(token, new SimpleRuleCoverage(token, Ref.empty()));
|
|
|
+ }
|
|
|
+
|
|
|
+ for(Rule rule : grammar.rules.values()) {
|
|
|
+ getRuleAliases(rule);
|
|
|
+ String ruleName = rule.name;
|
|
|
+ Ref<String> alias = Ref.ofNullable(aliases.get(ruleName));
|
|
|
+ rules.put(ruleName, new SimpleRuleCoverage(ruleName, alias));
|
|
|
+ }
|
|
|
+
|
|
|
+ for(String fqn : branchValidator) {
|
|
|
+ if(!fqn.startsWith(NodeSupport.QUALIFIER_NAME)) {
|
|
|
+ String[] m = fqn.split(NodeSupport.QUALIFIER_NAME);
|
|
|
+ String ruleName = m[0];
|
|
|
+ String qualifier = NodeSupport.QUALIFIER_NAME + m[1];
|
|
|
+ Ref<String> alias = Ref.ofNullable(aliases.get(ruleName + qualifier));
|
|
|
+ branches.put(qualifier, new SimpleBranchCoverage(ruleName, qualifier, alias));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ branches.values().forEach(branch -> {
|
|
|
+ rules.get(branch.rule()).branches().add(branch);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void getRuleAliases(Rule rule) {
|
|
|
+ if(rule.alt != null) {
|
|
|
+ for (Alternative alt : rule.alt) {
|
|
|
+ if (alt != null) {
|
|
|
+ String alias = null;
|
|
|
+ if(alt.ruleRefs.size() == 0 && alt.tokenRefs.size() == 1) {
|
|
|
+ alias = alt.tokenRefs.keySet().iterator().next();
|
|
|
+ }
|
|
|
+ if(alt.ruleRefs.size() == 1 && alt.tokenRefs.size() == 0) {
|
|
|
+ alias = alt.ruleRefs.keySet().iterator().next();
|
|
|
+ }
|
|
|
+ if(alias != null) {
|
|
|
+ int ri = rule.index;
|
|
|
+ int ai = alt.altNum;
|
|
|
+ String altName = branchLabels.get(ri, ai);
|
|
|
+
|
|
|
+ if(altName != null) {
|
|
|
+ aliases.put(rule.name + NodeSupport.QUALIFIER_NAME+ altName, alias);
|
|
|
+ }
|
|
|
+ else if(rule.alt.length == 2) {
|
|
|
+ aliases.put(rule.name, alias);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Collection<G4ParserCoverage.RuleCoverage> rules() {
|
|
|
+ return rules.values();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Collection<BranchCoverage> branches() {
|
|
|
+ return branches.values();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Ref<G4ParserCoverage.RuleCoverage> rule(String ruleName) {
|
|
|
+ return Ref.ofNullable(rules.get(ruleName));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Ref<G4ParserCoverage.BranchCoverage> branch(String ruleName) {
|
|
|
+ return Ref.ofNullable(branches.get(ruleName));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Data
|
|
|
private static final class ANTLRToolListenerAdapter implements ANTLRToolListener {
|
|
|
|