All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.modelcc.parser.fence.FenceParserFactory Maven / Gradle / Ivy

Go to download

ModelCC is a model-based parser generator (a.k.a. compiler compiler) that decouples language specification from language processing, avoiding some of the problems caused by grammar-driven parser generators. ModelCC receives a conceptual model as input, along with constraints that annotate it. It is then able to create a parser for the desired textual language and the generated parser fully automates the instantiation of the language conceptual model. ModelCC also includes a built-in reference resolution mechanism that results in abstract syntax graphs, rather than mere abstract syntax trees.

The newest version!
/*
 * ModelCC, distributed under ModelCC Shared Software License, www.modelcc.org
 */

package org.modelcc.parser.fence;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.modelcc.language.LanguageException;
import org.modelcc.language.LanguageSpecification;
import org.modelcc.language.factory.LanguageSpecificationFactory;
import org.modelcc.language.lexis.LexicalSpecification;
import org.modelcc.language.lexis.TokenSpecification;
import org.modelcc.language.metamodel.SimpleLanguageElement;
import org.modelcc.language.metamodel.CompositeLanguageElement;
import org.modelcc.language.metamodel.LanguageModel;
import org.modelcc.language.metamodel.LanguageElement;
import org.modelcc.lexer.Lexer;
import org.modelcc.lexer.LexerException;
import org.modelcc.lexer.LexerFactory;
import org.modelcc.lexer.recognizer.PatternRecognizer;
import org.modelcc.parser.ParserException;
import org.modelcc.parser.ParserFactory;
import org.modelcc.metamodel.Model;

/**
 * ModelCC Fence Parser Generator
 * 
 * @author Luis Quesada ([email protected])
 */
public class FenceParserFactory extends ParserFactory implements Serializable {

    /**
     * Creates a parser
     * @param m the model
     * @return the parser
     * @throws ParserException
     */
    public FenceParser createParser (Model m) throws ParserException 
    {
        return createParser (m,(Set)null);
    }

    /**
     * Creates a parser
     * @param m the model
     * @param lexer the lexer
     * @return the parser
     * @throws ParserException
     */
    public FenceParser createParser (Model m, Lexer lexer) throws ParserException 
    {
    	if (!(m instanceof LanguageModel))
    		throw new ParserException("Fence parsers need a LanguageModel as input.");
    	
        try {
            //Type erasure does not allow comparing the generated parser with a specific parser type. Check http://serdom.eu/ser/2007/03/25/java-generics-instantiating-objects-of-type-parameter-without-using-class-literal
            LanguageSpecificationFactory lsf = new LanguageSpecificationFactory();
            LanguageSpecification ls = lsf.create((LanguageModel)m);
            Fence gp = new Fence();

            FenceParser parser = new FenceParser(lexer,gp,ls.getSyntacticSpecification());
            return parser;
        } catch (LanguageException e) {
            throw new ParserException("Unable to create parser",e);
        }
    }

    /**
     * Creates a parser
     * @param m the model
     * @param skip the skip model
     * @return the parser
     * @throws ParserException
     */
    public FenceParser createParser (Model m, Model skip) throws ParserException 
    {
    	if (!(skip instanceof LanguageModel))
    		throw new ParserException("Fence parsers need a LanguageModel skip model as input.");
    	
        Set skipSet = new HashSet();
        
        if (skip != null)
            fillSkipSet(skipSet,(LanguageModel)skip,((LanguageModel)skip).getStart());
        
        return createParser(m,skipSet);
    }

    /**
     * Creates a parser
     * @param m the model
     * @param skip the skip set
     * @return the parser
     * @throws ParserException
     */
    public FenceParser createParser (Model m, Set skip) 
    		throws ParserException 
    {
    	if (!(m instanceof LanguageModel))
    		throw new ParserException("Fence parsers need a LanguageModel as input.");
        	
        try {
            //Type erasure does not allow comparing the generated parser with a specific parser type. Check http://serdom.eu/ser/2007/03/25/java-generics-instantiating-objects-of-type-parameter-without-using-class-literal
            LanguageSpecificationFactory lsf = new LanguageSpecificationFactory();
            LanguageSpecification ls = lsf.create((LanguageModel)m);
            Lexer gl = LexerFactory.create(addSkippedTokens(ls.getLexicalSpecification(),skip));
            FenceParser parser = new FenceParser(gl,new Fence(),ls.getSyntacticSpecification());
            return parser;
        } catch (LanguageException e) {
            throw new ParserException("Unable to create parser",e);
        } catch (LexerException e) {
            throw new ParserException("Unable to create lexer",e);
        }
    }

    
	private LexicalSpecification addSkippedTokens (LexicalSpecification ls, Set skip)
	{
        if (skip != null)
            for (PatternRecognizer recognizer: skip)
                ls.skipTokenSpecification(new TokenSpecification(null,recognizer));

        return ls;
	}
    
    private static void fillSkipSet(Set skipSet, LanguageModel skipModel, LanguageElement el) 
    {
    	if (el.getClass().equals(CompositeLanguageElement.class)) {
    		Logger.getLogger(FenceParserFactory.class.getName()).log(Level.SEVERE, "The skip model may not contain composite elements. Element {0} is composite.",new Object[]{el.getElementClass().getCanonicalName()});
    	} else if (el.getClass().equals(SimpleLanguageElement.class)) {
    		skipSet.add(((SimpleLanguageElement)el).getPatternRecognizer());
    	} else {
    		for (LanguageElement element: skipModel.getSubelements().get(el))
    			fillSkipSet(skipSet,skipModel,element);
    	}
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy