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

astra.ast.core.ASTRAClassElement Maven / Gradle / Ivy

The newest version!
package astra.ast.core;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import astra.ast.element.ConstantElement;
import astra.ast.element.FunctionElement;
import astra.ast.element.GRuleElement;
import astra.ast.element.InferenceElement;
import astra.ast.element.InitialElement;
import astra.ast.element.ModuleElement;
import astra.ast.element.PackageElement;
import astra.ast.element.RuleElement;
import astra.ast.element.TypesElement;
import astra.ast.visitor.Utilities;

public class ASTRAClassElement implements IElement {
	static Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);

	PackageElement packageElement;
	List imports = new LinkedList<>();
	ClassDeclarationElement declaration;
	List ontologies = new LinkedList<>();
	List initials = new LinkedList<>();
	List functions = new LinkedList<>();
	List inferences = new LinkedList<>();
	List grules = new LinkedList<>();
	List rules = new LinkedList<>();
	List modules = new LinkedList<>();
	List constants = new LinkedList<>();

	private Token first, last;
	private boolean local;
	
	public ASTRAClassElement(String source, String contents) throws ParseException {
		this(source, new ByteArrayInputStream(contents.getBytes()));
	}
	
	/**
	 * Main contstructor for ASTRAClassElement.  This constructor parses the given
	 * input stream and generates the ASTRA model for the class.  Exceptions are
	 * created for any parse errors.
	 * 
	 * NOTE: Upon completion, this will be a coarse grained AST for ASTRA, but
	 * it will not necessarily be semantically valid.  You should use the
	 * associated visitors to ensure semantic correctness.
	 *  
	 * @param source the name of the source file
	 * @param in the input stream
	 * @throws ParseException - generated for any parsing error
	 */
	public ASTRAClassElement(String source, InputStream in) throws ParseException {
			this(source, in, true);
	}
	
	public ASTRAClassElement(String source, InputStream in, boolean local) throws ParseException {
		this.local = local;
		ADTTokenizer tokenizer = new ADTTokenizer(in);
		ASTRAParser parser = new ASTRAParser(tokenizer);
		
		Token tok = tokenizer.nextToken();
		first = tok;
		if (tok.type == Token.PACKAGE) {
			List list = parser.readTo(Token.SEMI_COLON);
			packageElement = parser.createPackage(list.subList(0, list.size()-1));
			tok = tokenizer.nextToken();
		} else {
			packageElement = new PackageElement("", null, null, "");
		}

		while (!(tok.type == Token.AGENT || tok.type == Token.ABSTRACT)) {
			switch (tok.type) {
			case Token.PACKAGE:
				throw new ParseException("Package declaration must be the first line of the file", tok, tok);
			case Token.IMPORT:
				List list = parser.readTo(Token.SEMI_COLON);
				imports.add(parser.createImport(list.subList(0, list.size()-1)));
				tok = tokenizer.nextToken();
				break;
			default:
				throw new ParseException("Unexpected statement: " + tok.token, tok, tok);
			}
		}

		// Re-add the token because there are multiple possible first keywords for this class
		List list = parser.readTo(Token.LEFT_BRACE);
		list.add(0, tok);
		declaration = parser.createClassDeclaration(list);
		declaration.setParent(this);

		// Here we check that the Agent Name and Package correspond to the source name
		Utilities.validatePackageAndClassName(this, source);
		
		boolean finished = false;
		while (!finished) {
			try {
				tok = tokenizer.nextToken();
//				System.out.println("tok: " + tok.token);
				switch (tok.type) {
				case Token.MODULE:
					list = parser.readTo(Token.SEMI_COLON);
					modules.add((ModuleElement) parser.createModule(list.subList(0, list.size()-1)).setParent(this));
					break;
				case Token.TYPES:
					list = parser.readTo(Token.RIGHT_BRACE);
					ontologies.add(parser.createTypes(list.subList(0, list.size()-1)));
					break;
				case Token.INITIAL:
					list = parser.readTo(Token.SEMI_COLON);
					initials.addAll(parser.createInitial(list.subList(0, list.size()-1)));
					break;
				case Token.CONSTANT:
					list = parser.readTo(Token.SEMI_COLON);
					constants.addAll(parser.createConstant(list.subList(0, list.size()-1)));
					break;
				case Token.INFERENCE:
					list = parser.readTo(Token.SEMI_COLON);
					inferences.add((InferenceElement) parser.createInference(list.subList(0, list.size()-1)).setParent(this));
					break;
				case Token.GRULE:
				case Token.GOAL_TYPE:
					list = parser.readTo(Token.RIGHT_BRACE);
					grules.add((GRuleElement) parser.createGRule(list).setParent(this));
					break;
				case Token.ATOMIC:
				case Token.SYNCHRONIZED:
					list = parser.readTo(Token.RIGHT_BRACE);
					rules.add((RuleElement) parser.createSynchronizedRule(list).setParent(this));
					break;
				case Token.RULE:
					list = parser.readTo(Token.RIGHT_BRACE);
					rules.add((RuleElement) parser.createRule(list).setParent(this));
					break;
				case Token.FUNCTION:
					list = parser.readTo(Token.RIGHT_BRACE);
					functions.add((FunctionElement) parser.createFunction(list).setParent(this));
					break;
				case Token.RIGHT_BRACE:
					last = tok;
				case Token.EOF:
					finished = true;
					break;
				default:
					throw new ParseException("Unknown token: " + tok.token, tok);
				}
			} catch (ParseException e) {
				store(e);
			} catch (Throwable th) {
				store(new ParseException("Unexpected Error: " + th.getMessage(), th, 1, 1, 0));
				th.printStackTrace();
				logger.log(Level.SEVERE, "Unexpected Error", th);
			} finally {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
		
		Token token = null;
		List endList = new LinkedList();
		while((token = tokenizer.nextToken()) != Token.EOF_TOKEN) {
			endList.add(token);
		}
		if (!endList.isEmpty()) errorList.add( new ParseException("Code is outside the agent declaration", endList.get(0), endList.get(endList.size()-1)));
		
		for(InitialElement elem : initials) {
			elem.setParent(this);
		}
	}


	List errorList = new LinkedList();
	
	public void store(ParseException e) {
		errorList.add(e);
	}
	
	public List getErrorList() {
		return errorList;
	}
	
	public IElement[] getElements() {
		List elements = new ArrayList();
		elements.addAll(modules);
		elements.addAll(initials);
		elements.addAll(rules);
		elements.addAll(functions);
		return elements.toArray(new IElement[elements.size()]);
	}
	
	/**
	 * Returns all the rules specified in the agent class
	 * @return an array of rule elements
	 */
	public RuleElement[] getRules() {
		return rules.toArray(new RuleElement[] {});
	}
	
	public ModuleElement[] getModules() {
		return modules.toArray(new ModuleElement[] {});
	}
	
	public InitialElement[] getInitials() {
		return initials.toArray(new InitialElement[] {});
	}

	@Override
	public String getSource() {
		return null;
	}

	@Override
	public Object accept(IElementVisitor visitor, Object data) throws ParseException {
		return visitor.visit(this, data);
	}

	public PackageElement packageElement() {
		return packageElement;
	}

	public ImportElement[] imports() {
		return imports.toArray(new ImportElement[] {});
		
	}

	public ClassDeclarationElement getClassDeclaration() {
		return declaration;
	}

	public InferenceElement[] getInferences() {
		return inferences.toArray(new InferenceElement[] {});
	}

	public FunctionElement[] getFunctions() {
		return functions.toArray(new FunctionElement[] {});
	}

	public String getFilename() {
		if (packageElement == null) return declaration.name() + ".java";
		return packageElement.packageName().replace(".", "/") + "/" + declaration.name() + ".java";
	}

	@Override
	public IElement getParent() {
		return null;
	}

	@Override
	public IElement setParent(IElement parent) {
		return this;
	}

	@Override
	public int getBeginLine() {
		return first.beginLine;
	}

	public String getQualifiedName() {
		return (packageElement.packageName().equals("") ? "":(packageElement.packageName() + ".")) + declaration.name();
	}

	@Override
	public int getBeginColumn() {
		return first.beginColumn;
	}

	@Override
	public int charStart() {
		return first.charStart;
	}

	@Override
	public int charEnd() {
		return last.charEnd;
	}
	
	public String toString() {
		return this.getQualifiedName();
	}

	public List getOntologies() {
		return this.ontologies;
	}
	
	public boolean local() {
		return local;
	}
	
	public List getGRules() {
		return grules;
	}

	public List getConstants() {
		return constants;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy