gt: 			case token_g2cmemtr		:	parse_cuda_g2cmemtr(); break;
context: package omp2gpu.analysis;
  
  import java.io.*;
  import java.util.*;
  import java.lang.String;
  import cetus.hir.*;
  
  /**
   * @author Seyong Lee <lee222@purdue.edu>
   *         ParaMount Group 
   *         School of ECE, Purdue University
   *
   * CUDA directive parser
   */
  public class CudaParser
  {
  	private static String [] token_array;
  	private static int token_index;
  	private	static HashMap cuda_map;
  	private int debug_level;
  
  	public CudaParser() {
  	}
  
  	private static String get_token()
  	{
  		return token_array[token_index++];
  	}
  
  	// consume one token
  	private static void eat()
  	{
  		token_index++;
  	}
  
  	// match a token with the given string
  	private static boolean match(String istr)
  	{
  		boolean answer = check(istr);
  		if (answer == false) {
  			System.out.println("CudaParser Syntax Error");
  			System.out.println(display_tokens());
  		}
  		token_index++;
  		return answer;
  	}
  
  	// match a token with the given string, but do not consume a token
  	private static boolean check(String istr)
  	{
  		if ( end_of_token() ) 
  			return false;
  		return ( token_array[token_index].compareTo(istr) == 0 ) ? true : false;
  	}	
  
  	private static String display_tokens()
  	{
  		StringBuilder str = new StringBuilder(160);
  
  		for (int i=0; i<token_array.length; i++)
  		{
  			str.append("token_array[" + i + "] = " + token_array[i] + "\n");
  		}
  		return str.toString();
  	}
  
  	private static boolean end_of_token()
  	{
  		return (token_index >= token_array.length) ? true : false;
  	}
  
  	/**
  	 * CudaAnnotation is used for internally representing Cuda pragmas, which contain
  	 * Cuda-related user directives. Cuda pragmas are raw text right after parsing 
  	 * but converted to an internal annotation of this type.
  	 * 
  	 * The following user directives are supported:
  	 * #pragma cuda ainfo procname(proc-name) kernelid(kernel-id)
  	 * 
  	 * #pragma cuda cpurun [clause[[,] clause]...]
  	 * where clause is one of the following
  	 * 		c2gmemtr(list) 
  	 * 		noc2gmemtr(list) 
  	 * 		g2cmemtr(list) 
  	 *      nog2cmemtr(list)
  	 *      
  	 * #pragma cuda gpurun [clause[[,] clause]...]
  	 * where clause is one of the following
  	 * 		c2gmemtr(list) 
  	 * 		noc2gmemtr(list) 
  	 * 		g2cmemtr(list) 
  	 *      nog2cmemtr(list)
  	 * 		registerRO(list) 
  	 * 		registerRW(list) 
  	 * 		noregister(list)
  	 * 		sharedRO(list) 
  	 * 		sharedRW(list) 
  	 * 		noshared(list)
  	 * 		texture(list) 
  	 * 		notexture(list)
  	 * 		constant(list)
  	 * 		noconstant(list)
  	 *      maxnumofblocks(nblocks)
  	 *      noreductionunroll(list)
  	 *      nocudamalloc(list)
  	 *      nocudafree(list)
  	 *      cudafree(list)
  	 *      noploopswap
  	 *      noloopcollapse
  	 *      
  	 * #pragma cuda nogpurun
  	 */
  	// returns TRUE, if the cuda pragma will be attached to the following non-pragma 
  	// statement. Or, it returns false, if the pragma is a standalone pragma
  	public static boolean parse_cuda_pragma(HashMap input_map, String [] str_array)
  	{
  		cuda_map = input_map;
  		token_array = str_array;
  		//token_index = 2; // There is a leading space, and "cuda" has already been matched
  		token_index = 1; // "cuda" has already been matched
  
  		PrintTools.println(display_tokens(), 9);
  
  		String construct = "cuda_" + get_token();
  		switch (cuda_pragma.valueOf(construct)) {
  			case cuda_ainfo 		: parse_cuda_ainfo(); return true;
  			case cuda_gpurun 		: parse_cuda_gpurun(); return true;
  			case cuda_cpurun		: parse_cuda_cpurun(); return true;
  			case cuda_nogpurun 		: parse_cuda_nogpurun(); return true;
  //		default : throw new NonOmpDirectiveException();
  			default : CudaParserError("Not Supported Construct");
  		}
  		return true;		// meaningless return because it is unreachable
  	}
  	
  	/** ---------------------------------------------------------------
  	 *		Cuda ainfo Construct
  	 *
  	 *		#pragma cuda ainfo procname(proc-name) kernelid(id) new-line
  	 *			structured-block
  	 *
  	 * --------------------------------------------------------------- */
  	private static void parse_cuda_ainfo()
  	{
  		PrintTools.println("CudaParser is parsing [ainfo] directive", 2);
  		addToMap("ainfo", "true");
  		
  		while (end_of_token() == false) 
  		{
  			String clause = "token_" + get_token();
  			PrintTools.println("clause=" + clause, 2);
  			switch (cuda_clause.valueOf(clause)) {
  			case token_procname		:	parse_cuda_procname(); break;
  			case token_kernelid	:	parse_cuda_kernelid(); break;
  			default : CudaParserError("NoSuchCudaConstruct : " + clause);
  			}
  		}
  	}
  
  	/** ---------------------------------------------------------------
  	 *		Cuda gpurun Construct
  	 *
  	 *		#pragma cuda gpurun [clause[[,] clause]...] new-line
  	 *			structured-block
  	 *
  	 *		where clause is one of the following
  	 * 		c2gmemtr(list) 
  	 * 		noc2gmemtr(list) 
  	 * 		g2cmemtr(list) 
  	 *      nog2cmemtr(list)
  	 * 		registerRO(list) 
  	 * 		registerRW(list) 
  	 * 		noregister(list)
  	 * 		sharedRO(list) 
  	 * 		sharedRW(list) 
  	 * 		noshared(list) 
  	 * 		texture(list) 
  	 * 		notexture(list) 
  	 * 		constant(list)
  	 * 		noconstant(list)
  	 *      maxnumofblocks(nblocks)
  	 *      noreductionunroll(list)
  	 *      nocudamalloc(list)
  	 *      nocudafree(list)
  	 *      cudafree(list)
  	 *      noploopswap
  	 *      noloopcollapse
  	 *      threadblocksize(N)
  	 * --------------------------------------------------------------- */
  	private static void parse_cuda_gpurun()
  	{
  		PrintTools.println("CudaParser is parsing [gpurun] directive", 2);
  		addToMap("gpurun", "true");
  
  		while (end_of_token() == false) 
  		{
  			String clause = "token_" + get_token();
  			PrintTools.println("clause=" + clause, 2);
  			switch (cuda_clause.valueOf(clause)) {
  			case token_c2gmemtr		:	parse_cuda_c2gmemtr(); break;
  			case token_noc2gmemtr	:	parse_cuda_noc2gmemtr(); break;
  			case token_g2cmemtr		:	parse_cuda_g2cmemtr(); break;
  			case token_nog2cmemtr	:	parse_cuda_nog2cmemtr(); break;
  			case token_registerRO		:	parse_cuda_registerRO(); break;
  			case token_registerRW		:	parse_cuda_registerRW(); break;
  			case token_noregister		:	parse_cuda_noregister(); break;
  			case token_sharedRO 		:	parse_cuda_sharedRO(); break;
  			case token_sharedRW 		:	parse_cuda_sharedRW(); break;
  			case token_noshared 		:	parse_cuda_noshared(); break;
  			case token_texture 		:	parse_cuda_texture(); break;
  			case token_notexture 		:	parse_cuda_notexture(); break;
  			case token_constant		:	parse_cuda_constant(); break;
  			case token_noconstant		:	parse_cuda_noconstant(); break;
  			case token_maxnumofblocks		:	parse_cuda_maxnumofblocks(); break;
  			case token_noreductionunroll	:	parse_cuda_noreductionunroll(); break;
  			case token_nocudamalloc	:	parse_cuda_nocudamalloc(); break;
  			case token_nocudafree	:	parse_cuda_nocudafree(); break;
  			case token_cudafree	:	parse_cuda_cudafree(); break;
  			case token_noploopswap	:	addToMap("noploopswap", "true"); break;
  			case token_noloopcollapse	:	addToMap("noloopcollapse", "true"); break;
  			case token_threadblocksize		:	parse_cuda_threadblocksize(); break;
  			default : CudaParserError("NoSuchCudaConstruct : " + clause);
  			}
  		}
  	}
  	
  	/** -----------------------------------
  	 *		Cuda nogpurun Construct
  	 *
  	 *		#pragma cuda nogpurun new-line
  	 *			structured-block
  	 *
  	 * ------------------------------------ */
  	private static void parse_cuda_nogpurun()
  	{
  		PrintTools.println("CudaParser is parsing [nogpurun] directive", 2);
  		addToMap("nogpurun", "true");
  		
  		while (end_of_token() == false) 
  		{
  			String clause = "token_" + get_token();
  			PrintTools.println("[WARNING] any clause (" + clause +") attached to " +
  					"cuda nogpurun will be ignored", 0);
  		}
  	}
  	
  	/** ---------------------------------------------------------------
  	 *		Cuda User Directive
  	 *
  	 *		kernelid(id) procname(name) [clause[[,] clause]...] new-line
  	 *
  	 *		where clause is one of the following
  	 *      nogpurun
  	 * 		c2gmemtr(list) 
  	 * 		noc2gmemtr(list) 
  	 * 		g2cmemtr(list) 
  	 *      nog2cmemtr(list)
  	 * 		registerRO(list) 
  	 * 		registerRW(list) 
  	 * 		noregister(list)
  	 * 		sharedRO(list) 
  	 * 		sharedRW(list) 
  	 * 		noshared(list) 
  	 * 		texture(list) 
  	 * 		notexture(list) 
  	 * 		constant(list)
  	 * 		noconstant(list)
  	 *      maxnumofblocks(nblocks)
  	 *      noreductionunroll(list)
  	 *      nocudamalloc(list)
  	 *      nocudafree(list)
  	 *      cudafree(list)
  	 *      noploopswap
  	 *      noloopcollapse
  	 *      threadblocksize(N)
  	 * --------------------------------------------------------------- */
  
  	public static HashMap<String,HashMap<String, Object>> parse_cuda_userdirective(String[] str_array)
  	{
  		cuda_map = new HashMap<String, Object>();
  		HashMap userDirectives = new HashMap<String, HashMap<String, Object>>();
  		token_array = str_array;
  		token_index = 0; 
  		PrintTools.println(display_tokens(), 9);
  
  		PrintTools.println("CudaParser is parsing user-directves", 2);
  		String kernelid = null;
  		String procname = null;
  		String kernelname = null;
  		String clause = "token_" + get_token();
  		if( clause.equals("token_kernelid") ) {
  			match("(");
  			kernelid = get_token();
  			match(")");
  		} else {
  			PrintTools.println("[ERROR in parse_cuda_userdirective()] kernelid is missing; " +
  					"current user directive line will be ignored.", 0);
  			PrintTools.println("Current token is " + clause, 0);
  			return null;
  		}
  		clause = "token_" + get_token();
  		if( clause.equals("token_procname") ) {
  			match("(");
  			procname = get_token();
  			match(")");
  		} else {
  			PrintTools.println("[ERROR in parse_cuda_userdirective()] procname is missing; " +
  					"current user directive line will be ignored.", 0);
  			return null;
  		}
  		kernelname = procname.concat(kernelid);
  
  		while (end_of_token() == false) 
  		{
  			clause = "token_" + get_token();
  			PrintTools.println("clause=" + clause, 2);
  			switch (cuda_clause.valueOf(clause)) {
  			case token_nogpurun		:	parse_cuda_nogpurun(); break;
  			case token_c2gmemtr		:	parse_cuda_c2gmemtr(); break;
  			case token_noc2gmemtr	:	parse_cuda_noc2gmemtr(); break;
  