package damp.ekeko.snippets; import java.io.IOException; import java.util.Collection; import java.util.IdentityHashMap; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import damp.ekeko.snippets.SnippetParser.DirectivesContext; import damp.ekeko.snippets.SnippetParser.MetaContext; import damp.ekeko.snippets.SnippetParser.PostmetaContext; import damp.ekeko.snippets.SnippetParser.PremetaContext; public class SnippetExtractor extends SnippetBaseVisitor<Void> { class SnippetBounds { public int openBracket; public int closeBracket; public int startAt; public int stopAt; public String directives; public String toString() { return "[=" + openBracket + " ]@=" + startAt + " [=" + stopAt + " ]= " + closeBracket + " -> " + directives; } } public Collection<SnippetBounds> getSnippetBounds() { return snippets.values(); } public Collection<SnippetBounds> extractSnippetBounds(ParseTree tree) { tree.accept(this); return getSnippetBounds(); } public IdentityHashMap<ParserRuleContext, SnippetBounds> snippets = new IdentityHashMap<ParserRuleContext, SnippetBounds>(); @Override public Void visitMeta(MetaContext ctx) { SnippetBounds bounds = new SnippetBounds(); snippets.put(ctx, bounds); return super.visitMeta(ctx); } @Override public Void visitPremeta(PremetaContext ctx) { SnippetBounds snippetBounds = snippets.get(ctx.getParent()); TerminalNode open = ctx.OPEN(); Token openToken = open.getSymbol(); snippetBounds.openBracket = openToken.getStartIndex(); TerminalNode middle = ctx.MIDDLE(); Token middleToken = middle.getSymbol(); snippetBounds.startAt = middleToken.getStartIndex(); snippetBounds.stopAt = middleToken.getStopIndex(); return super.visitPremeta(ctx); } @Override public Void visitDirectives(DirectivesContext ctx) { SnippetBounds snippetBounds = snippets.get(ctx.getParent().getParent()); snippetBounds.directives = ctx.getText(); return super.visitDirectives(ctx); } @Override public Void visitPostmeta(PostmetaContext ctx) { SnippetBounds snippetBounds = snippets.get(ctx.getParent()); TerminalNode close = ctx.CLOSE(); Token closeToken = close.getSymbol(); snippetBounds.closeBracket = closeToken.getStartIndex(); return super.visitPostmeta(ctx); } public static ExtractedSnippet extractSnippetBounds(String snippet) { ANTLRInputStream input = new ANTLRInputStream(snippet); SnippetLexer lexer = new SnippetLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); SnippetParser parser = new SnippetParser(tokens); ParseTree tree = parser.snippet(); SnippetExtractor extractor = new SnippetExtractor(); Collection<SnippetBounds> extractedSnippetBounds = extractor.extractSnippetBounds(tree); char[] characters = snippet.toCharArray(); for(SnippetBounds sb : extractedSnippetBounds) { characters[sb.openBracket] = ' '; for(int i = sb.startAt; i <= sb.closeBracket; i++) characters[i] = ' '; } ExtractedSnippet extractedSnippet = new ExtractedSnippet(); extractedSnippet.bounds = extractedSnippetBounds; extractedSnippet.snippet = new String(characters); return extractedSnippet; } public static void main(String[] args) throws IOException { ExtractedSnippet snippet = SnippetExtractor.extractSnippetBounds("[[int]@[foo] [x]@[relax]]@[dunno];"); System.out.println(snippet.snippet); for(SnippetBounds bounds : snippet.bounds) System.out.println(bounds); } }