|
@@ -1,5 +1,6 @@
|
|
|
package net.ranides.assira.grammar.impl;
|
|
package net.ranides.assira.grammar.impl;
|
|
|
|
|
|
|
|
|
|
+import lombok.Data;
|
|
|
import net.ranides.assira.collection.lists.ListUtils;
|
|
import net.ranides.assira.collection.lists.ListUtils;
|
|
|
import net.ranides.assira.collection.maps.CrossMap;
|
|
import net.ranides.assira.collection.maps.CrossMap;
|
|
|
import net.ranides.assira.collection.maps.OpenCrossMap;
|
|
import net.ranides.assira.collection.maps.OpenCrossMap;
|
|
@@ -11,9 +12,14 @@ import net.ranides.assira.grammar.G4Parser;
|
|
|
import net.ranides.assira.generic.Ref;
|
|
import net.ranides.assira.generic.Ref;
|
|
|
import net.ranides.assira.grammar.G4ParserCoverage;
|
|
import net.ranides.assira.grammar.G4ParserCoverage;
|
|
|
import net.ranides.assira.text.StringUtils;
|
|
import net.ranides.assira.text.StringUtils;
|
|
|
|
|
+import org.antlr.runtime.ANTLRStringStream;
|
|
|
import org.antlr.runtime.RecognitionException;
|
|
import org.antlr.runtime.RecognitionException;
|
|
|
import org.antlr.runtime.tree.CommonTree;
|
|
import org.antlr.runtime.tree.CommonTree;
|
|
|
|
|
+import org.antlr.runtime.tree.TreeVisitor;
|
|
|
|
|
+import org.antlr.runtime.tree.TreeVisitorAction;
|
|
|
|
|
+import org.antlr.v4.Tool;
|
|
|
import org.antlr.v4.analysis.LeftRecursiveRuleAltInfo;
|
|
import org.antlr.v4.analysis.LeftRecursiveRuleAltInfo;
|
|
|
|
|
+import org.antlr.v4.parse.GrammarASTAdaptor;
|
|
|
import org.antlr.v4.runtime.CharStreams;
|
|
import org.antlr.v4.runtime.CharStreams;
|
|
|
import org.antlr.v4.runtime.CommonTokenStream;
|
|
import org.antlr.v4.runtime.CommonTokenStream;
|
|
|
import org.antlr.v4.runtime.LexerInterpreter;
|
|
import org.antlr.v4.runtime.LexerInterpreter;
|
|
@@ -22,12 +28,15 @@ import org.antlr.v4.runtime.Token;
|
|
|
import org.antlr.v4.runtime.Vocabulary;
|
|
import org.antlr.v4.runtime.Vocabulary;
|
|
|
import org.antlr.v4.runtime.misc.Pair;
|
|
import org.antlr.v4.runtime.misc.Pair;
|
|
|
import org.antlr.v4.runtime.tree.RuleNode;
|
|
import org.antlr.v4.runtime.tree.RuleNode;
|
|
|
|
|
+import org.antlr.v4.tool.ANTLRMessage;
|
|
|
|
|
+import org.antlr.v4.tool.ANTLRToolListener;
|
|
|
import org.antlr.v4.tool.Alternative;
|
|
import org.antlr.v4.tool.Alternative;
|
|
|
import org.antlr.v4.tool.Grammar;
|
|
import org.antlr.v4.tool.Grammar;
|
|
|
import org.antlr.v4.tool.LabelElementPair;
|
|
import org.antlr.v4.tool.LabelElementPair;
|
|
|
import org.antlr.v4.tool.Rule;
|
|
import org.antlr.v4.tool.Rule;
|
|
|
import org.antlr.v4.tool.ast.AltAST;
|
|
import org.antlr.v4.tool.ast.AltAST;
|
|
|
import org.antlr.v4.tool.ast.GrammarAST;
|
|
import org.antlr.v4.tool.ast.GrammarAST;
|
|
|
|
|
+import org.antlr.v4.tool.ast.GrammarRootAST;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
@@ -46,9 +55,14 @@ public class G4ParserInterpreter implements G4Parser {
|
|
|
|
|
|
|
|
private final CrossMap<String, String, Integer> expressionLabels;
|
|
private final CrossMap<String, String, Integer> expressionLabels;
|
|
|
|
|
|
|
|
- public G4ParserInterpreter(String grammar, G4ErrorHandler handler) {
|
|
|
|
|
|
|
+ public G4ParserInterpreter(String grammar, String imports, G4ErrorHandler handler) {
|
|
|
try {
|
|
try {
|
|
|
- this.grammar = new Grammar(grammar);
|
|
|
|
|
|
|
+ if(imports == null) {
|
|
|
|
|
+ this.grammar = new Grammar(grammar, new ANTLRToolListenerAdapter(handler));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.grammar = newGrammar(grammar, imports, handler);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
this.handler = handler;
|
|
this.handler = handler;
|
|
|
this.branchLabels = deduceBranchLabels(this.grammar);
|
|
this.branchLabels = deduceBranchLabels(this.grammar);
|
|
|
this.expressionLabels = deduceExpressionLabels(this.grammar);
|
|
this.expressionLabels = deduceExpressionLabels(this.grammar);
|
|
@@ -63,6 +77,39 @@ public class G4ParserInterpreter implements G4Parser {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private Grammar newGrammar(String grammarText, String imports, G4ErrorHandler handler) throws RecognitionException {
|
|
|
|
|
+ Tool tool = new Tool();
|
|
|
|
|
+ tool.addListener(new ANTLRToolListenerAdapter(handler));
|
|
|
|
|
+
|
|
|
|
|
+ ANTLRStringStream in = new ANTLRStringStream(grammarText);
|
|
|
|
|
+ in.name = "((string))";
|
|
|
|
|
+
|
|
|
|
|
+ GrammarRootAST ast = tool.parse(in.name, in);
|
|
|
|
|
+ if ( ast==null ) {
|
|
|
|
|
+ throw new UnsupportedOperationException();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (ast.tokenStream == null) {
|
|
|
|
|
+ throw new IllegalStateException("expected ast to have a token stream");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Grammar out = new Grammar(tool, ast);
|
|
|
|
|
+
|
|
|
|
|
+ in.name = out.fileName = out.name + ".g4";
|
|
|
|
|
+ tool.libDirectory = imports;
|
|
|
|
|
+
|
|
|
|
|
+ new TreeVisitor(new GrammarASTAdaptor()).visit(ast, new TreeVisitorAction() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Object pre(Object t) { ((GrammarAST)t).g = out; return t; }
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Object post(Object t) { return t; }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ tool.process(out, false);
|
|
|
|
|
+
|
|
|
|
|
+ return out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Tricky method: we deduce alternative labels for every rule
|
|
* Tricky method: we deduce alternative labels for every rule
|
|
|
*/
|
|
*/
|
|
@@ -188,7 +235,7 @@ public class G4ParserInterpreter implements G4Parser {
|
|
|
public G4ParserCoverage rules() {
|
|
public G4ParserCoverage rules() {
|
|
|
Vocabulary v = grammar.getVocabulary();
|
|
Vocabulary v = grammar.getVocabulary();
|
|
|
List<String> tokens = ListUtils.produce(v.getMaxTokenType() + 1, v::getSymbolicName);
|
|
List<String> tokens = ListUtils.produce(v.getMaxTokenType() + 1, v::getSymbolicName);
|
|
|
- throw new UnsupportedOperationException("TODO"); // @TODO implement
|
|
|
|
|
|
|
+ throw new UnsupportedOperationException("TODO"); // @TODO implement that
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private class MyRoot extends RootAbstract {
|
|
private class MyRoot extends RootAbstract {
|
|
@@ -247,4 +294,25 @@ public class G4ParserInterpreter implements G4Parser {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ @Data
|
|
|
|
|
+ private static final class ANTLRToolListenerAdapter implements ANTLRToolListener {
|
|
|
|
|
+
|
|
|
|
|
+ private final G4ErrorHandler handler;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void info(String msg) {
|
|
|
|
|
+ handler.onError(msg, new G4Exception(msg));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void error(ANTLRMessage msg) {
|
|
|
|
|
+ handler.onError(msg.toString(), msg.getCause());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void warning(ANTLRMessage msg) {
|
|
|
|
|
+ handler.onError(msg.toString(), msg.getCause());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|