/*
* Copyright (C) 2011 Laurent Caillette
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.novelang.parser.antlr;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonErrorNode;
import org.antlr.runtime.tree.RewriteCardinalityException;
import org.antlr.runtime.tree.Tree;
import org.novelang.common.Problem;
import org.novelang.common.SyntacticTree;
//import NovelangLexer;
//import AllTokens;
/**
* @author Laurent Caillette
*/
public abstract class AbstractDelegatingParser {
protected final NovelangParser antlrParser;
protected final NovelangLexer antlrLexer;
private final GrammarDelegate delegate;
public AbstractDelegatingParser( final String text, final GrammarDelegate delegate ) {
this.delegate = delegate ;
final CharStream stream = new ANTLRStringStream( text );
antlrLexer = new NovelangLexer( stream );
antlrLexer.setProblemDelegate( delegate ) ;
final CommonTokenStream tokens = new CommonTokenStream( antlrLexer );
antlrParser = new NovelangParser( tokens ) ;
final CustomTreeAdaptor treeAdaptor = new CustomTreeAdaptor( delegate.getLocationFactory() );
delegate.setAdaptor( treeAdaptor ) ;
delegate.setTokenNames( antlrParser.tokenNames ) ;
antlrParser.setTreeAdaptor( treeAdaptor ) ;
antlrParser.setParserDelegate( delegate ) ;
}
public boolean hasProblem() {
return delegate.getProblems().iterator().hasNext() ;
}
public Iterable< Problem > getProblems() {
final List< Problem > problems = Lists.newArrayList() ;
Iterables.addAll( problems, delegate.getProblems() ) ;
return ImmutableList.copyOf( problems ) ;
}
/**
* Calls specific parsing method and returns the raw result.
*
* @return a non-null instance of the parsing result object (the one containing the
* {@link org.antlr.runtime.tree.Tree} object that is a {@link CommonErrorNode}
* or a {@link SyntacticTree}.
*/
protected abstract Object callParserMethod() throws RecognitionException ;
public final SyntacticTree parse() {
final Object tree;
try {
tree = callParserMethod();
} catch( RecognitionException e ) {
getDelegate().report( e ) ;
return null ;
} catch( RewriteCardinalityException e ) {
getDelegate().report(
e.getClass() + ": " + e.getMessage(),
antlrLexer.getLine(),
antlrLexer.getCharPositionInLine()
) ;
return null ;
}
final SyntacticTree result ;
if( tree instanceof CommonErrorNode ) {
getDelegate().report( ( ( CommonErrorNode ) tree ).trappedException ) ;
result = null ;
} else {
result = TreeConverter.convert( ( Tree ) tree, getDelegate() ) ;
// Statistics.logStatistics( result ) ;
}
return result ;
}
public GrammarDelegate getDelegate() {
return delegate ;
}
}