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

org.modelcc.language.metamodel.LanguageModel 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.metamodel;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.modelcc.lexer.recognizer.PatternRecognizer;
import org.modelcc.metamodel.Model;

/**
 * Language model.
 * 
 * @author Luis Quesada ([email protected]) & Fernando Berzal ([email protected])
 */
public final class LanguageModel extends Model implements Serializable,Cloneable 
{
    /**
     * The start element of this model.
     */
    private LanguageElement start;

    /**
     * Delimiters of this model.
     */
    private Set delimiters;

    /**
     * ModelElement precedence map.
     */
    private Map> precedences;


    /**
     * ModelElement default element map.
     */
    private Map> defaultElement;

    /**
     * Constructor.
     * @param elements the set of elements of this model.
     * @param start the start element of this model
     * @param delimiters the delimiters of this model
     * @param precedences the element precedence map
     * @param subelements the element subclass map
     * @param superelements the element superclass map
     * @param classToElement the class to element map
     */
    public LanguageModel(Set elements,LanguageElement start,Set delimiters,Map> precedences,Map> subelements,Map superelements,Map classToElement,Map> defaultElement) 
    {
    	super(elements,subelements,superelements,classToElement);
    	
    	// Language model specifics
        this.start = start;
        this.delimiters = delimiters;
        this.precedences = precedences;
        this.defaultElement = defaultElement;
    }


    /**
     * @return the start element of this model
     */
    public LanguageElement getStart() {
        return start;
    }

    /**
     * @return the delimiters of this model
     */
    public Set getDelimiters() {
        return Collections.unmodifiableSet(delimiters);
    }

    /**
     * @return the element precedences map
     */
    public Map> getPrecedences() {
        return Collections.unmodifiableMap(precedences);
    }

    /**
     * @return the defaultElement
     */
    public Map> getDefaultElement() {
        return Collections.unmodifiableMap(defaultElement);
    }

    
    @Override
	public LanguageModel clone(){
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            ByteArrayOutputStream bOs = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bOs);
            oos.writeObject(this);
            ois = new ObjectInputStream(new ByteArrayInputStream(bOs.toByteArray()));
        	LanguageModel ret = (LanguageModel)ois.readObject();
            return ret;

        } catch (Exception e) {
        	e.printStackTrace();
            return null;
        }finally {
            if (oos != null)
                try {
                    oos.close();
                } catch (IOException e) {

                }
            if (ois != null)
                try {
                    ois.close();
                } catch (IOException e) {

                }
        }
    }

	public void addPrecedence(LanguageElement me, LanguageElement other) {
		Set precs1 = precedences.get(me);
		if (precs1 == null) {
			precs1 = new HashSet();
			precedences.put(me,precs1);
		}
		precs1.add(other);
		Set precs2 = precedences.get(other);
		if (precs2 != null) {
			precs2.remove(me);
			if (precs2.isEmpty())
				precedences.remove(other);
		}
	}

    public boolean checkPrecedences() 
    {
    	Set pool = new HashSet();
    	pool.addAll(getElements());

    	// Token specifications preceded by any token specification in the pool.
    	Set precededs;

    	Iterator ite;
    	LanguageElement ts;
    	Set pset;

    	boolean found; // Whether any new token specification has been added to the sorted list.



    	while (!pool.isEmpty()) {

    		found = false;

    		// Update precededs list.
    		precededs = new HashSet();
    		for (ite = pool.iterator();ite.hasNext();) {
    			ts = ite.next();
    			pset = precedences.get(ts);
    			if (pset != null) {
    				precededs.addAll(pset);
    			}
    		}

    		// Adds news unprecededs.
    		for (ite = pool.iterator();ite.hasNext();) {
    			ts = ite.next();
    			if (!precededs.contains(ts)) {
    				ite.remove();
    				found = true;
    			}
    		}

    		if (!found) {
    			// List of conflicting elements.
    			// String list = new String();
    			// for (ite = pool.iterator();ite.hasNext();)
    			//    list += " "+ite.next().getElementClass().getCanonicalName();
    			return false;
    		}
    	}

    	return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy