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

org.modelcc.language.lexis.LexicalSpecificationFactory 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.language.lexis;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.modelcc.language.CyclicPrecedenceException;
import org.modelcc.language.metamodel.LanguageModel;

/**
 * Lexical specification factory.
 * 
 * @author Luis Quesada ([email protected]) & Fernando Berzal ([email protected])
 */
public final class LexicalSpecificationFactory implements Serializable 
{
	private LexicalSpecification lexis;

    /**
     * Default constructor.
     */
    public LexicalSpecificationFactory() 
    {
    	lexis = new LexicalSpecification();
    }

    /**
     * Add token specification.
     * @param ts the token specification to be added.
     */
    public void addTokenSpecification(TokenSpecification ts) 
    {
        if (ts != null)
            lexis.addTokenSpecification(ts);
    }

    /**
     * Skip token specification.
     * @param ts the token specification to be skipped.
     */
    public void skipTokenSpecification(TokenSpecification ts) 
    {
        if (ts != null)
            lexis.skipTokenSpecification(ts);
    }    
    
    /**
     * Removes a token specification.
     * @param ts the token specification to remove.
     */
    public void removeTokenSpecification(TokenSpecification ts) 
    {
    	if (ts!=null)
    		lexis.removeTokenSpecification(ts);
    }

    /**
     * Adds a precedence relationship between tokens.
     * @param ts1 the token that precedes.
     * @param ts2 the token that is preceded.
     */
    public void addPrecedence (TokenSpecification ts1,TokenSpecification ts2) 
    {
    	lexis.addPrecedence(ts1, ts2);
    }

    /**
     * Removes a precedence relationship between tokens.
     * @param ts1 the token that precedes.
     * @param ts2 the token that is preceded.
     */
    public void removePrecedence(TokenSpecification ts1,TokenSpecification ts2) 
    {
    	lexis.removePrecedence(ts1, ts2);
    }

    /**
     * Create a lexical specification.
     * @throws CyclicTokenPrecedenceException
     * @return the lexical specification.
     */
    public LexicalSpecification create() 
    	throws CyclicPrecedenceException 
    {
    	return create(null);
    }
    
    /**
     * Create a lexical specification
     * @param model
     * @return
     * @throws CyclicPrecedenceException
     */
    public LexicalSpecification create(LanguageModel model) 
    	throws CyclicPrecedenceException 
    {
		Set pool = new HashSet();
        pool.addAll(lexis.getTokenSpecifications());

        Set preceded;
        List tokens = new ArrayList();

        boolean found;

        while (!pool.isEmpty()) {

        	found = false;
        	// Token specifications preceded by any token specification in the pool.
        	preceded = new HashSet();
        	
        	for (TokenSpecification ts: pool) {
        		Set pset = lexis.getPrecedences(ts);
        		if (pset != null) {
        			preceded.addAll(pset);
        		}
        	}

        	for (Iterator ite = pool.iterator(); ite.hasNext();) {
        		TokenSpecification ts = ite.next();
        		if (!preceded.contains(ts)) {
        			tokens.add(ts);
        			ite.remove();
        			found = true;
        		}
        	}

        	if (!found)
        		throw new CyclicPrecedenceException("Cyclic token precedence exception: "+cycleMessage(pool));
        }

        lexis.setTokenSpecifications(tokens);
        return lexis;
    }
    
    private String cycleMessage(Set tokens)
    {
		String list = "";
		
		for (TokenSpecification token: tokens)
			list += " "+token.getType();

		return list;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy