options {
  JAVA_UNICODE_ESCAPE = true;
  STATIC=false;
}

PARSER_BEGIN(InstanceSpecificationParser)

/*
 * Copyright (c) 2006 Borland Software Corporation
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Michael Golubev (Borland) - initial API and implementation
 */
package org.eclipse.uml2.diagram.clazz.parser.instance;

import java.io.*;
import java.util.*;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.uml2.diagram.parser.*;
import org.eclipse.uml2.diagram.parser.lookup.LookupSuite;
import org.eclipse.uml2.diagram.parser.lookup.LookupResolver;
import org.eclipse.uml2.uml.*;

public class InstanceSpecificationParser extends ExternalParserBase {
	private InstanceSpecification mySubject;
	
    private static class ClassifierLookupCallback implements LookupResolver.Callback {
    	private final InstanceSpecification mySubject;

		public ClassifierLookupCallback(InstanceSpecification subject){
			mySubject = subject;
    	}
    	
    	public void lookupResolved(NamedElement resolution) {
    		if (resolution instanceof Classifier){
    			mySubject.getClassifiers().add(resolution);
    		}
    	}
    }

    public InstanceSpecificationParser(){
    	this(new StringReader(""));
    }
    
    public InstanceSpecificationParser(LookupSuite lookup){
    	this();
    	setLookupSuite(lookup);
    }

	public EClass getSubjectClass(){
		return UMLPackage.eINSTANCE.getInstanceSpecification();
	}
	
	public void parse(EObject target, String text) throws ExternalParserException {
		checkContext();	
		ReInit(new StringReader(text));
		mySubject = (InstanceSpecification)target;
		Declaration();
		mySubject = null;
	}
	
	public InstanceSpecification parseNew(String text) throws ExternalParserException {
		InstanceSpecification instance = UMLFactory.eINSTANCE.createInstanceSpecification();
		parse(instance, text);
		return instance;	
	}
	
	protected static int parseInt(Token t) throws ParseException {
		if (t.kind != InstanceSpecificationParserConstants.INTEGER_LITERAL){
			throw new IllegalStateException("Token: " + t + ", image: " + t.image);
		}
		try {
			return Integer.parseInt(t.image); //XXX: "0005", "99999999999999999999999"
		} catch (NumberFormatException e){
			throw new ParseException("Not supported integer value:" + t.image);
		}
	}
	
}

PARSER_END(InstanceSpecificationParser)

/* WHITE SPACE */

SPECIAL_TOKEN :
{
  " "
| "\t"
}

/* SEPARATORS */
TOKEN :
{
	< SLASH: "/" >
|	< COLON: ":" >
|	< EQUALS: "=" >
|	< LBRACKET: "[" >
|	< RBRACKET: "]" >
|	< LCURLY: "{" >
|	< RCURLY: "}" >
|	< COMMA: "," >
}

/* SPECIAL_MEANING */
TOKEN :
{
	< PLUS: "+" >
|	< MINUS: "-" >
|	< NUMBER_SIGN: "#" >
|	< TILDE: "~" >
|	< DOT: "." >
|	< STAR: "*" >
}

/* MODIFIERS */
TOKEN :
{
	< READ_ONLY: "readOnly" >
|	< UNION: "union" >
|	< SUBSETS: "subsets" >
|	< REDEFINES: "redefines" >
|	< ORDERED: "ordered" >
|	< UNORDERED: "unordered" > 
|	< UNIQUE: "unique" >
|	< NON_UNIQUE: "nonunique" >
}
	
/* LITERALS */
TOKEN: 
{
	< INTEGER_LITERAL: ["0"-"9"] (["0"-"9"])* >
}
  
TOKEN :
{
  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
|
  < #LETTER:
      [
       "\u0024",
       "\u0041"-"\u005a",
       "\u005f",
       "\u0061"-"\u007a",
       "\u00c0"-"\u00d6",
       "\u00d8"-"\u00f6",
       "\u00f8"-"\u00ff",
       "\u0100"-"\u1fff",
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uf900"-"\ufaff"
      ]
  >
|
  < #DIGIT:
      [
       "\u0030"-"\u0039",
       "\u0660"-"\u0669",
       "\u06f0"-"\u06f9",
       "\u0966"-"\u096f",
       "\u09e6"-"\u09ef",
       "\u0a66"-"\u0a6f",
       "\u0ae6"-"\u0aef",
       "\u0b66"-"\u0b6f",
       "\u0be7"-"\u0bef",
       "\u0c66"-"\u0c6f",
       "\u0ce6"-"\u0cef",
       "\u0d66"-"\u0d6f",
       "\u0e50"-"\u0e59",
       "\u0ed0"-"\u0ed9",
       "\u1040"-"\u1049"
      ]
  >
}

void Declaration() :
{}
{
	LOOKAHEAD(2)
	(
		AnonymousUnnamed()
	)
	|
	(
		[ InstanceName() ]
		[ InstanceType() ]
	) <EOF>
}

void AnonymousUnnamed() :
{}
{
	<COLON> { mySubject.setName(null); mySubject.getClassifiers().clear(); }
}

void InstanceName() :
{
	String name;
}
{
	name = NameWithSpaces() 
	{
		mySubject.setName(name);
	}
}

void InstanceType() :
{
	String type;
}
{
	(
		<COLON> type = NameWithSpaces() { applyLookup(Type.class, type, new ClassifierLookupCallback(mySubject)); }
		(
			<COMMA> type = NameWithSpaces() { applyLookup(Type.class, type, new ClassifierLookupCallback(mySubject)); }
		)*
	)
}

String NameWithSpaces() :
{
	StringBuffer result = new StringBuffer();
	Token t;
}
{
	(
		t = <IDENTIFIER> { result.append(t.image); } 
		( t = <IDENTIFIER> { result.append(' '); result.append(t.image); } ) *
	)
	{
		return result.toString();
	}
}
