/******************************************************************************* * Copyright (c) 2007, 2008 Edgar Espina. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.deved.antlride.internal.core.parser; import java.util.HashSet; import java.util.List; import java.util.Set; import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.CommonToken; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.tree.CommonTreeNodeStream; import org.antlr.runtime.tree.Tree; import org.antlr.tool.ANTLRErrorListener; import org.antlr.tool.Message; import org.antlr.tool.ToolMessage; import org.deved.antlride.core.build.AntlrSourceParserRepository; import org.deved.antlride.core.model.IGrammar; import org.deved.antlride.core.model.IImport; import org.deved.antlride.internal.core.model.AAbstractGrammarBuilder; import org.deved.antlride.internal.core.model.AGrammar; import org.deved.antlride.internal.core.parser.ANTLRParser.grammarDef_return; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; public class AntlrGrammarBuilder extends AAbstractGrammarBuilder { private static class ErrorCounter implements ANTLRErrorListener { private int errors; public void error(Message msg) { errors++; } public void error(ToolMessage msg) { error((Message) msg); } public void info(String msg) { } public void warning(Message msg) { } } @Override public IGrammar process(final String content) { final AGrammar grammar = isBasicMode() ? new AGrammar(content) : new AGrammar(filename, content); final ErrorCounter counter = new ErrorCounter(); try { ANTLRLexer lexer = new ANTLRLexer(new ANTLRStringStream(content)) { @Override public void emitErrorMessage(String msg) { counter.errors++; super.emitErrorMessage(msg); } }; CommonTokenStream tokens = new CommonTokenStream(lexer); ANTLRParser parser = new ANTLRParser(tokens) { @Override public void emitErrorMessage(String msg) { counter.errors++; super.emitErrorMessage(msg); } }; grammarDef_return grammarDef = parser.grammarDef(); CommonTreeNodeStream nodes = new CommonTreeNodeStream( (Tree) grammarDef.tree); nodes.setTokenStream(tokens); ANTLRTreeWalker walker = new ANTLRWalker(nodes); DefaultGrammarBuilder builder = new DefaultGrammarBuilder(grammar); walker.grammarDef(builder); builder.build(); @SuppressWarnings("unchecked") List<CommonToken> tokenList = tokens.getTokens(); // int k = 0; for (CommonToken token : tokenList) { if (token.getType() == ANTLRLexer.SL_COMMENT || token.getType() == ANTLRLexer.ML_COMMENT) { grammar.addComment(token.getText()); } } // load dependent grammars if (!isBasicMode() && grammar.hasImports()) { IImport[] imports = grammar.getImports().getImports(); Set<String> gnames = new HashSet<String>(); for (IImport imp : imports) { gnames.add(imp.getElementName()); } gnames.remove(grammar.getElementName()); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); for (String gname : gnames) { IPath dependentPath = grammar.getFolder().append(gname) .addFileExtension("g"); IFile dependentFile = root.getFile(dependentPath); if (dependentFile.exists()) { IGrammar dependentGrammar = AntlrSourceParserRepository .getGrammar(dependentPath); grammar.addDependent(dependentGrammar); } } } } catch (Exception ex) { ex.printStackTrace(); } grammar.setValid(counter.errors == 0); return grammar; } private boolean isBasicMode() { return filename == null; } }