/**********************************************************************
 * Copyright (c) 2006, 2007 IBM 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ptp.pldt.openmp.analysis.PAST;

import java.util.Iterator;
import java.util.LinkedList;

import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.c.CScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ptp.pldt.common.util.Utility;
import org.eclipse.ptp.pldt.openmp.analysis.OpenMPError;
import org.eclipse.ptp.pldt.openmp.analysis.OpenMPErrorManager;
import org.eclipse.ptp.pldt.openmp.analysis.dictionary.Dictionary;
import org.eclipse.ptp.pldt.openmp.analysis.dictionary.Symbol;
import org.eclipse.ptp.pldt.openmp.analysis.parser.OpenMPScanner;
import org.eclipse.ptp.pldt.openmp.analysis.parser.OpenMPToken;

/**
 * Factory to convert PASTPragma-->PASTOMPPragma
 * @author pazel
 *
 */
public class PASTOMPFactory
{
    protected PASTPragma          pragma_       = null;
    protected PASTOMPPragma       ompPragma_    = null;
    protected IASTTranslationUnit ast_          = null;
    protected Dictionary          dictionary_   = null;
    
    protected static boolean      traceOn_      = false;
    private static final boolean traceOn=false;
    
    protected OpenMPScanner scanner_ = null;
    protected OpenMPToken   token_   = null;
    
    //protected ScannerCallbackManager callbackManager_ = null;
    
    /**
     * Factory used only by this class
     * @param pragma - PASTPragma
     */
    protected PASTOMPFactory(PASTPragma          pragma, 
                             IASTTranslationUnit ast,
                             Dictionary          dictionary)
    {
        pragma_     = pragma;
        scanner_    = new OpenMPScanner(pragma_.getContent());
        ast_        = ast;
        dictionary_ = dictionary;
        
        //experiment();
        
        if (traceOn_)
          readTokens();
        
        //otherinit(null);
    }
    
    private void experiment()
    {
        IASTFileLocation loc = pragma_.getFileLocation();
        if (loc!=null) {
            IDocument document = Utility.getDocument(loc.getFileName());
            if (document != null) {
                try {
                  String txt = document.get(pragma_.getLocalOffset(), pragma_.getLength());
                  System.out.println(txt);
                }
                catch(Exception e) {}
            }
        }
    }

    
    /**
     * Return either omp or non-omp pragma
     * @return
     */
    protected PASTPragma retrievePragma()
    {
        return (ompPragma_!=null ? ompPragma_ : pragma_);
    }
    
    /**
     * Factory for making the PASTOMPPragma structure
     *               if possible
     * @param pragma     : PASTPragma 
     * @param ast        : IASTTranslationUnit
     * @param dictionary : Dictionary
     * @return: PASTPragma (or PASTOMPPragma if do-able)
     */
    public static PASTPragma makePASTOMP(PASTPragma          pragma, 
                                         IASTTranslationUnit ast, 
                                         Dictionary          dictionary)
    {
        PASTOMPFactory factory = new PASTOMPFactory(pragma, ast, dictionary);
        factory.parse();
        factory.locateRegion();
        return factory.retrievePragma();
    }
    
    /**
     * Parse the pragma context for OMP
     * @return boolean
     */
    protected boolean parse() 
    {
        // The first two tokens should be # and pragma
    	OpenMPToken tok=nextToken();
    	if(tok==null){
    		if(traceOn)System.out.println("PASTOMPFactory.parser()..null token, ignored.");
    		return false; //robustly handle empty tokens
    	}
        if (tok.getType()!=OpenMPScanner.mpPound) return false;
        tok=nextToken();
        if (tok.getType()!=OpenMPScanner.mpPragma) return false;
        
        // if next is not omp - this is not an openmp directive
        if (nextToken().getType()!=OpenMPScanner.mpOmp) 
            return false;
        
        // Construct the OpenMP pragma
        ompPragma_ = new PASTOMPPragma(pragma_);
        
        // The next token sets the type
        nextToken();
        OpenMPToken typeToken = token_;   // determines type, used for error message
        if (token_==null)  return false;
        ompPragma_.setOMPType(setOMPType(token_.getType()));
        
        if (token_==null)  return false;
        
        switch(ompPragma_.getOMPType()) {
            case PASTOMPPragma.OmpParallel:
                completeParallel();
                break;
            case PASTOMPPragma.OmpFor:
                completeFor();
                break;
            case PASTOMPPragma.OmpParallelFor:
                completeParallelFor();
                break;
            case PASTOMPPragma.OmpSections:
                completeSections();
                break;
            case PASTOMPPragma.OmpParallelSections:
                completeParallelSections();
                break;
            case PASTOMPPragma.OmpSingle:
                completeSingle();
                break;
            case PASTOMPPragma.OmpMaster:
                break;
            case PASTOMPPragma.OmpCritical:
                break;
            case PASTOMPPragma.OmpBarrier:
                break;
            case PASTOMPPragma.OmpAtomic:
                break;
            case PASTOMPPragma.OmpSection:
                break;
            case PASTOMPPragma.OmpFlush:
                completeFlush();
                break;
            case PASTOMPPragma.OmpOrdered:
                break;
            case PASTOMPPragma.OmpThreadPrivate:
                completeThreadPrivate();
                break;
            case PASTOMPPragma.OmpUnknown:
                String typeString = (typeToken!=null ? typeToken.getImage(): "");
                handleProblem("Unexpected token '"+typeString+"'", OpenMPError.ERROR);
                break;
        }
        
        // all remaining tokens are bogus
        while(token_!=null) {
            handleProblem("Unexpected token '"+token_.getImage()+"'", OpenMPError.ERROR);
            nextToken();
        }
        
        return true;
    }
    
    /**
     * Set the type of OpenMP statement based on keyword
     * @param t
     * @return
     *    Note: always exit with the current token being the next to process, i.e.
     *          call nextToken()
     */
    protected int setOMPType(int t)
    {
       nextToken();    // advance to next token 
       switch(t) {
           case OpenMPScanner.mpParallel:
               if (token_==null) return PASTOMPPragma.OmpParallel;
               if (token_.getType()==OpenMPScanner.mpFor) {
                   nextToken(); return PASTOMPPragma.OmpParallelFor;
               }
               else if (token_.getType()==OpenMPScanner.mpSections) {
                   nextToken(); return PASTOMPPragma.OmpParallelSections;
               }
               return PASTOMPPragma.OmpParallel;
           case OpenMPScanner.mpFor:
               return PASTOMPPragma.OmpFor;
           case OpenMPScanner.mpSections:
               return PASTOMPPragma.OmpSections;
           case OpenMPScanner.mpSection:
               return PASTOMPPragma.OmpSection;
           case OpenMPScanner.mpSingle:
               return PASTOMPPragma.OmpSingle;
           case OpenMPScanner.mpMaster:
               return PASTOMPPragma.OmpMaster;
           case OpenMPScanner.mpCritical:
               return PASTOMPPragma.OmpCritical;
           case OpenMPScanner.mpBarrier:
               return PASTOMPPragma.OmpBarrier;
           case OpenMPScanner.mpAtomic:
               return PASTOMPPragma.OmpAtomic;
           case OpenMPScanner.mpFlush:
               return PASTOMPPragma.OmpFlush;
           case OpenMPScanner.mpOrdered:
               return PASTOMPPragma.OmpOrdered;
           case OpenMPScanner.mpThreadPrivate:
               return PASTOMPPragma.OmpThreadPrivate;
       }
       return PASTOMPPragma.OmpUnknown;
    }
    
    /**
     * Parse a list of identifiers, e.g. as from shared(...)
     * @return OpenMPToken []
     */
    protected OpenMPToken [] getIdentifierList()
    {
        LinkedList l = new LinkedList();
        
        if (token_==null)  return null;
        //if (token_.getType()!=IToken.tLPAREN) return null;
        
        // look for lists like a,b,c
        boolean commaNext = false;
        nextToken();
        while(token_!=null) {
           if (commaNext) {
               if (token_.getType()!=IToken.tCOMMA)   break; 
               else  { commaNext=false;  nextToken(); continue; }
           }
           // whatever it is, add to the list
           l.add(token_);
           commaNext=true;
           nextToken();
        }
        
        // build the list
        OpenMPToken [] ompl = new OpenMPToken[l.size()];
        int count=0;
        for(Iterator i = l.iterator(); i.hasNext();) {
            ompl[count++] = (OpenMPToken)i.next();
            // check to see if in dictionary
            Symbol [] symbols = dictionary_.getSymbolsFor(ompl[count-1].getImage());
            if (symbols.length==0) {
                handleProblem("Undefined symbol '"+ompl[count-1].getImage()+"'", OpenMPError.ERROR);  
            }
            else {
                // try to find at least one (non-global that is in same scope as pragma
                boolean found=false;
                for(int j=0; j<symbols.length; j++) {
                    IASTNode fctn = symbols[j].getDefiningFunction();
                    if (fctn==null || !(fctn instanceof IASTFunctionDefinition)) continue;
                    if (isSymbolRelevant(symbols[j])) { found=true; break; }
                }
                if (!found)
                    handleProblem("Symbol out of scope: '"+ompl[count-1].getImage()+"'", OpenMPError.ERROR); 
            }
        }
        
        // rule: always leave one ahead
        nextToken();
        
        return ompl;
    }
    
    /**
     * See if symbol is a local variable in scope to pragma
     * @param symbol - Symbol
     * @return boolean
     */
    protected boolean isSymbolRelevant(Symbol symbol)
    {   
    	if(traceOn)System.out.println("Symbol: "+symbol.getName()+"  PASTOMPFactory.isSymbolRelevant()");
        IASTNode node = null;
        IASTNode parent,gp=null;
		try {
			// node=symbol.getScope().getPhysicalNode(); // no longer in CDT 4.0
			// BRT replacement for getPhysicalNode() for CDT 4.0
			// The following probably isn't an ideal solution (using Discouraged access methods)
			// but seems to work for now. 
			// alternatively I tried implementing: symbol.getPhysicalNode() but could not get the same answer from there.
			
			IScope scope=symbol.getScope();
			// see: http://dev.eclipse.org/mhonarc/lists/cdt-dev/msg08653.html
			// Another alternative would be to cast to CScope and do cScope.getPhysicalNode() from there.
			node = ASTInternal.getPhysicalNodeOfScope(scope);

		} catch (Exception e) {
			return false;
		}
        
        Utility.Location l = Utility.getLocation(node);
        int nodeOffset = (l!=null ? l.getLow()  : 0);     //728
        int nodeEndset = (l!=null ? l.getHigh() : 0);       //745
        if(traceOn)System.out.println("node: "+node.getRawSignature()+" nodeOffset: "+nodeOffset+" nodeEndset= "+nodeEndset);
        
        int pOffset = pragma_.getLocalOffset();            //822
        int pEndset = pOffset+pragma_.getLength()-1;       //864
        if(traceOn)System.out.println(("pragma pOffset= "+pOffset+" pEndset= "+pEndset));
        
        boolean tf = ((nodeEndset<pOffset || pEndset<nodeOffset) ? false : true);  //false
        if (!tf)  return tf;
        
        // See if the declaration succeeds the pragma
        Utility.Location dl = Utility.getLocation(symbol.getDeclarator());
        if (dl==null)  return false;
        if(traceOn)System.out.println("dl.getLow()="+dl.getLow()+" pOffset="+pOffset+
        		" > is: "+(dl.getLow()>pOffset));
        
        return (dl.getLow()>pOffset ? false : true);
    }
    
    /**
     * Acquire the next token
     * @return OpenMPToken
     */
    protected OpenMPToken nextToken()
    {
        // Following in case of backup
        if (token_!=null && token_.getNext()!=null) {
            token_ = token_.getNext();
            return token_;
        }
        
        // chain to last one and move on
        OpenMPToken token = scanner_.nextToken();
        if (token_!=null)
            token_.setNext(token);
        token_ = token;
        return token_;
    }
    
    /**
     * Get current token so as to mark (in code) where we were
     * @return OpenMPToken
     */
    protected OpenMPToken mark()
    {
        if (token_==null)
            token_ = nextToken();
        return token_;
    }
    
    /**
     * Reset token queue (nextToken() get one after this one)
     * @param token
     */
    protected void backupTo(OpenMPToken token)
    {
        token_ = token;
    }
    
    /**
     * Test the parser
     *
     */
    private void readTokens()
    {
        OpenMPScanner scanner = new OpenMPScanner(pragma_.getContent());
        
        OpenMPToken token = null;
        do {
            token = scanner.nextToken();
            if (token!=null)
              System.out.println("Token:"+token.getImage()+" type="+token.getType());
         } while(token!=null);
    }
    
    /**
     * Complete the parsing of #pragma omp parallel
     *
     */
    private void completeParallel()
    {
        boolean bShared       = false;
        boolean bPrivate      = false;
        boolean bFirstPrivate = false;
        boolean bDefault      = false;
        boolean bReduction    = false;
        boolean bCopyin       = false;
        boolean bIf           = false;
        boolean bNumthreads   = false;
        
        while(token_!=null) {
            switch(token_.getType()){
                case OpenMPScanner.mpShared:
                    if (!bShared) 
                        bShared = setShared();
                    break;
                case OpenMPScanner.mpPrivate:
                    if (!bPrivate) 
                        bPrivate = setPrivate();
                    break;
                case OpenMPScanner.mpFirstprivate:
                    if (!bFirstPrivate) 
                        bFirstPrivate = setFirstPrivate();
                    break;
               case OpenMPScanner.mpDefault:
                    if (!bDefault)
                        bDefault = setDefault();
                    break;
               case OpenMPScanner.mpReduction:
                   if (!bReduction)
                       bReduction = setReduction();
                   break;
               case OpenMPScanner.mpCopyin:
                   if (!bCopyin) 
                       bCopyin = setCopyin();
                   break;
               case OpenMPScanner.mpIf:
                   if (!bIf)  
                       bIf = setIf();
                   break;
               case OpenMPScanner.mpNumthreads:
                   if (!bNumthreads)
                       bNumthreads = setNumThreads();
                   break;
               default:
                   handleProblem("Unexpected token "+token_.getImage(), OpenMPError.ERROR);
                   nextToken();
                   break;
            }
        }
    }
    
    /**
     * Complete parsing #paragma omp for
     *
     */
    private void completeFor()
    {
        boolean bPrivate      = false;
        boolean bFirstPrivate = false;
        boolean bLastPrivate  = false;
        boolean bReduction    = false;
        boolean bOrdered      = false;
        boolean bSchedule     = false;
        boolean bNowait       = false;
        
        while(token_!=null) {
            switch(token_.getType()){
                case OpenMPScanner.mpPrivate:
                    if (!bPrivate)
                        bPrivate = setPrivate();
                    break;
                case OpenMPScanner.mpFirstprivate:
                    if (!bFirstPrivate) 
                        bFirstPrivate = setFirstPrivate();
                    break;
                case OpenMPScanner.mpLastprivate:
                    if (!bLastPrivate)  
                        bLastPrivate = setLastPrivate(); 
                    break;
                case OpenMPScanner.mpReduction:
                    if (!bReduction)
                        bReduction = setReduction();
                  break;
                case OpenMPScanner.mpOrdered:
                    if (!bOrdered) {
                      ompPragma_.setOrdered(true);  bOrdered=true; }
                    nextToken();
                    break;
                case OpenMPScanner.mpSchedule:
                    if (!bSchedule)
                        bSchedule = setSchedule();
                    break;
                case OpenMPScanner.mpNowait:
                    if (!bNowait) {
                        ompPragma_.setNoWait(true);  bNowait=true;  }
                    nextToken();
                    break;
                default:
                    handleProblem("Unexpected token "+token_.getImage(), OpenMPError.ERROR);
                    nextToken();
                    break;
            }
        }
    }
    
    
    /**
     * Complete parsing #paragma omp parallel for
     *
     */
    private void completeParallelFor()
    {
        boolean bShared       = false;
        boolean bPrivate      = false;
        boolean bFirstPrivate = false;
        boolean bLastPrivate  = false;
        boolean bDefault      = false;
        boolean bReduction    = false;
        boolean bCopyin       = false;
        boolean bIf           = false;
        boolean bOrdered      = false;
        boolean bSchedule     = false;
        
        while(token_!=null) {
            switch(token_.getType()){
                case OpenMPScanner.mpShared:
                    if (!bShared) 
                        bShared = setShared();
                    break;
                case OpenMPScanner.mpPrivate:
                    if (!bPrivate)
                        bPrivate = setPrivate();
                    break;
                case OpenMPScanner.mpFirstprivate:
                    if (!bFirstPrivate) 
                        bFirstPrivate = setFirstPrivate();
                    break;
                case OpenMPScanner.mpLastprivate:
                    if (!bLastPrivate)  
                        bLastPrivate = setLastPrivate(); 
                    break;
                case OpenMPScanner.mpDefault:
                    if (!bDefault)
                        bDefault = setDefault();
                    break;
                case OpenMPScanner.mpReduction:
                    if (!bReduction)
                        bReduction = setReduction();
                  break;
                case OpenMPScanner.mpCopyin:
                    if (!bCopyin) 
                        bCopyin = setCopyin();
                    break;
                case OpenMPScanner.mpIf:
                    if (!bIf)  
                        bIf = setIf();
                    break;
                case OpenMPScanner.mpOrdered:
                    if (!bOrdered) {
                      ompPragma_.setOrdered(true);  bOrdered=true; }
                    nextToken();
                    break;
                case OpenMPScanner.mpSchedule:
                    if (!bSchedule)
                        bSchedule = setSchedule();
                    break;
                default:
                    handleProblem("Unexpected token "+token_.getImage(), OpenMPError.ERROR);
                    nextToken();
                    break;
            }
        }
    }
    
    
    /**
     * Complete parsing #pragma omp parallel sections
     *
     */
    private void completeParallelSections()
    {
        boolean bShared       = false;
        boolean bPrivate      = false;
        boolean bFirstPrivate = false;
        boolean bLastPrivate  = false;
        boolean bDefault      = false;
        boolean bReduction    = false;
        boolean bCopyin       = false;
        boolean bIf           = false;
        
        while(token_!=null) {
            switch(token_.getType()){
                case OpenMPScanner.mpShared:
                    if (!bShared) 
                        bShared = setShared();
                    break;
                case OpenMPScanner.mpPrivate:
                    if (!bPrivate)
                        bPrivate = setPrivate();
                    break;
                case OpenMPScanner.mpFirstprivate:
                    if (!bFirstPrivate) 
                        bFirstPrivate = setFirstPrivate();
                    break;
                case OpenMPScanner.mpLastprivate:
                    if (!bLastPrivate)  
                        bLastPrivate = setLastPrivate(); 
                    break;
                case OpenMPScanner.mpDefault:
                    if (!bDefault)
                        bDefault = setDefault();
                    break;
                case OpenMPScanner.mpReduction:
                    if (!bReduction)
                        bReduction = setReduction();
                  break;
                case OpenMPScanner.mpCopyin:
                    if (!bCopyin) 
                        bCopyin = setCopyin();
                    break;
                case OpenMPScanner.mpIf:
                    if (!bIf)  
                        bIf = setIf();
                    break;
                default:
                    handleProblem("Unexpected token "+token_.getImage(), OpenMPError.ERROR);
                    nextToken();
                    break;
            }
        }
    }

    
    /**
     * Complete parse of #pragma omp sections
     *
     */
    private void completeSections()
    {
        boolean bPrivate      = false;
        boolean bFirstPrivate = false;
        boolean bLastPrivate  = false;
        boolean bReduction    = false;
        boolean bNowait       = false;
        
        while(token_!=null) {
            switch(token_.getType()){
                case OpenMPScanner.mpPrivate:
                    if (!bPrivate)
                        bPrivate = setPrivate();
                     break;
                case OpenMPScanner.mpFirstprivate:
                    if (!bFirstPrivate) 
                        bFirstPrivate = setFirstPrivate();
                   break;
                case OpenMPScanner.mpLastprivate:
                    if (!bLastPrivate)  
                        bLastPrivate = setLastPrivate(); 
                    break;
                case OpenMPScanner.mpReduction:
                    if (!bReduction)
                        bReduction = setReduction();
                    break;
                case OpenMPScanner.mpNowait:
                    if (!bNowait) {
                        ompPragma_.setNoWait(true);  bNowait=true;  }
                    nextToken();
                    break;
                 default:
                    handleProblem("Unexpected token "+token_.getImage(), OpenMPError.ERROR);
                    nextToken();
                    break;
            }
        }
        
    }
    
    /**
     * Complete options for the #pragma omp single
     *
     */
    private void completeSingle()
    {
        boolean bPrivate      = false;
        boolean bFirstPrivate = false;
        boolean bCopyPrivate  = false;
        boolean bNowait       = false;
        
        while(token_!=null) {
            switch(token_.getType()){
                case OpenMPScanner.mpPrivate:
                    if (!bPrivate)
                        bPrivate = setPrivate();
                   break;
                case OpenMPScanner.mpFirstprivate:
                    if (!bFirstPrivate) 
                        bFirstPrivate = setFirstPrivate();
                    break;
                case OpenMPScanner.mpCopyprivate:
                    if (!bCopyPrivate) 
                       bCopyPrivate = setCopyPrivate();
                    break;
                case OpenMPScanner.mpNowait:
                    if (!bNowait) {
                        ompPragma_.setNoWait(true);  bNowait=true;  }
                    nextToken();
                    break;
                default:
                    handleProblem("Unexpected token "+token_.getImage(), OpenMPError.ERROR);
                    nextToken();
                    break;
            }
        }
        
    }
    
    /**
     * Complete the options for the #pragma omp flush
     *
     */
    private void completeFlush()
    {
        if (token_==null || token_.getType()!=IToken.tLPAREN)  return;
        
        OpenMPToken []   list = getIdentifierList();
        
        ompPragma_.setPrivateList(list);
    }

    
    /**
     * Complete the options for the #pragma omp threadprivate
     *
     */
    private void completeThreadPrivate()
    {
        if (token_==null || token_.getType()!=IToken.tLPAREN)  return;
        
        OpenMPToken []   list = getIdentifierList();
        
        ompPragma_.setThreadPrivateList(list);
    }
    
    /**
     * Translate the type of reduction operato
     * @return int (that PASTOMPPragma understands)
     */
    private int getReductionOperator()
    {
        switch(token_.getType()) {
            case IToken.tPLUS:
                return PASTOMPPragma.OmpOpPlus;
            case IToken.tSTAR:
                return PASTOMPPragma.OmpOpMult;
            case IToken.tMINUS:
                return PASTOMPPragma.OmpOpMinus;
            case IToken.tAMPER:
                return PASTOMPPragma.OmpOpBAnd;
            case IToken.tXOR:
                return PASTOMPPragma.OmpOpBXor;
            case IToken.tBITOR:
                return PASTOMPPragma.OmpOpBOr;
            case IToken.tAND:
                return PASTOMPPragma.OmpOpLAnd;
            case IToken.tOR:
                return PASTOMPPragma.OmpOpLOr;
            default:
                return PASTOMPPragma.OmpOpUnknown;
        }
    }
    
    /**
     * Translate the kind of schedule
     * @return int (that PASTOMPPragma understands)
     */
    private int getScheduleKind()
    {
        switch(token_.getType()) {
            case OpenMPScanner.mpStatic:
                return PASTOMPPragma.OmpSKStatic;
            case OpenMPScanner.mpDynamic:
                return PASTOMPPragma.OmpSKDynamic;
            case OpenMPScanner.mpGuided:
                return PASTOMPPragma.OmpSKGuided;
            case OpenMPScanner.mpRuntime:
                return PASTOMPPragma.OmpSKRuntime;
            default:
                return PASTOMPPragma.OmpSKUnknown;
        }
    }
    
    /**
     * Get the schedule expression
     * @return OpenMPToken []
     */
    private OpenMPToken [] getExpression()
    {
        LinkedList l = new LinkedList();
        int        parenCt=1;
        
        nextToken();
        while(token_!=null) {
            if (token_.getType()==IToken.tRPAREN){
                parenCt--;  if (parenCt==0)  break;  
                            else {l.add(token_); }  // end of schedule clause
            }
            else if (token_.getType()==IToken.tCOMMA) {
                if (parenCt==1)  break; else l.add(token_);               // another way to exit
            }
            else if (token_.getType()==IToken.tLPAREN) 
            { parenCt++;  l.add(token_);  }
            else 
                l.add(token_);
            nextToken();
        }
        
        OpenMPToken [] list = new OpenMPToken[l.size()];
        for(int i=0; i<l.size(); i++)
            list[i] = (OpenMPToken)l.get(i);
        
        nextToken();   // move ahead
        return list;
    }
    
    private boolean setIf()
    {
        nextToken();
        OpenMPToken [] list = getExpression();
        ompPragma_.setIfExpression(list); 
        return true;
    }
    
    
    private boolean setPrivate()
    {
        nextToken();
        OpenMPToken [] list = getIdentifierList();
        ompPragma_.setPrivateList(list); 
        return true;
    }
    
    private boolean setFirstPrivate()
    {
        nextToken();
        OpenMPToken [] list = getIdentifierList();
        ompPragma_.setFirstPrivateList(list); 
        return true;
    }
    
    private boolean setLastPrivate()
    {
        nextToken();
        OpenMPToken [] list = getIdentifierList();
        ompPragma_.setLastPrivateList(list); 
        return true;
    }
   
    private boolean setShared()
    {
        nextToken();
        OpenMPToken [] list = getIdentifierList();
        ompPragma_.setSharedList(list); 
        return true;
    }
    
    private boolean setCopyin()
    {
       nextToken();
       OpenMPToken [] list = getIdentifierList();
       ompPragma_.setCopyinList(list); 
       return true;
    }
    
    
    private boolean setCopyPrivate()
    {
       nextToken();
       OpenMPToken [] list = getIdentifierList();
       ompPragma_.setCopyPrivateList(list); 
       return true;
    }

    
    private boolean setDefault()
    {
        boolean shared = false;
        nextToken();
        if (token_.getType()==IToken.tLPAREN) {
            nextToken();
            if (token_.getType()==OpenMPScanner.mpShared)    shared=true;
            else if (token_.getType()==OpenMPScanner.mpNone) shared=false;
            else return false;
            nextToken();  // get the paren
            if (token_==null || token_.getType()!=IToken.tRPAREN)  return false;
            ompPragma_.setDefault(shared ? PASTOMPPragma.OmpShared : 
                                           PASTOMPPragma.OmpNone);
            nextToken();
            return true;
        }
        return false;
    }
    
    private boolean setReduction()
    {
        nextToken();
        if (token_.getType()==IToken.tLPAREN) {
            nextToken();
            int ro = getReductionOperator();
            nextToken();
            if (token_!=null && token_.getType()==IToken.tCOLON) {
                OpenMPToken [] rlist = getIdentifierList();
                ompPragma_.setReductionOperator(ro);
                ompPragma_.setReductionList(rlist);  
                return true;
            }
            return false;
        }
        return false;
    }
    
    private boolean setNumThreads()
    {
        nextToken();
        if (token_.getType()==IToken.tLPAREN) {
            OpenMPToken [] expr = getExpression();
            if (token_==null || token_.getType()!=IToken.tRPAREN) return false;
            ompPragma_.setNumThreadsExpr(expr);
            return true;
        }
        return false;
    }
    
    private boolean setSchedule()
    {
        nextToken();
        if (token_.getType()==IToken.tLPAREN) {
            nextToken();
            int kind = getScheduleKind();
            nextToken();
            if (token_!=null && token_.getType()==IToken.tCOMMA) {
                OpenMPToken [] expr = getExpression();
                ompPragma_.setScheduleKind(kind);
                ompPragma_.setChunkExpression(expr);
                return true;
            }
            return false;
        }
        return false;
    }
    
    
    // We are presently unsure of what to do with all the following stuff:
//    protected static final ScannerProblemFactory spf = new ScannerProblemFactory();
//    protected ScannerCallbackManager callbackManager;
//    protected static char[] EMPTY_CHAR_ARRAY = new char[0];
//    
//    protected void otherinit(ISourceElementRequestor requestor)
//    {
//        callbackManager = new ScannerCallbackManager(new NullSourceElementRequestor());
//    }
    
    /**
     * handleProblem
     * @param description - String
     * @param severity    - int
     */
    protected void handleProblem(String  description, int severity)
    {
        OpenMPError error = new OpenMPError(description, 
                                            pragma_.getContainingFilename(),
                                            pragma_.getStartingLine(),
                                            severity);
        OpenMPErrorManager.getCurrentErrorManager().addError(error);
        ompPragma_.addProblem(error);  // we really don't need this, but may be useful later
    }
    
    /**
     * lFind the associated region to the current pragma
     *
     */
    private void locateRegion()
    {
        if (ompPragma_==null)  return;
        
        switch (ompPragma_.getOMPType()) {
            // followed by structured region
            case PASTOMPPragma.OmpParallel:
            case PASTOMPPragma.OmpSections:
            case PASTOMPPragma.OmpSection:
            case PASTOMPPragma.OmpParallelSections:
            case PASTOMPPragma.OmpSingle:
            case PASTOMPPragma.OmpMaster:
            case PASTOMPPragma.OmpCritical:
            case PASTOMPPragma.OmpOrdered:
                determineRegion(STRUCTURED_BLOCK, ompPragma_);
                break;
                
            // Must be followed by FOR
            case PASTOMPPragma.OmpFor:
            case PASTOMPPragma.OmpParallelFor:
                determineRegion(FOR_BLOCK, ompPragma_);
                break;

            // Stands alone
            case PASTOMPPragma.OmpBarrier:
            case PASTOMPPragma.OmpFlush:
            case PASTOMPPragma.OmpThreadPrivate:
                determineRegion(LOCATION_ONLY, ompPragma_);
                break;
            
            // Followed by expression
            case PASTOMPPragma.OmpAtomic:
                determineRegion(EXPRESSION_BLOCK, ompPragma_);
                break;
            case PASTOMPPragma.OmpUnknown:
                break;
        }
    }
    
    public static final int STRUCTURED_BLOCK   = RegionDeterminationVisitor.STRUCTURED_BLOCK;
    public static final int FOR_BLOCK          = RegionDeterminationVisitor.FOR_BLOCK;
    public static final int EXPRESSION_BLOCK   = RegionDeterminationVisitor.EXPRESSION_BLOCK;
    public static final int LOCATION_ONLY      = RegionDeterminationVisitor.LOCATION_ONLY;
    
    /**
     * Determine that code region affilated with a pragma & the peer node
     * @param type - int (see constatns above)
     * @param ompPragma - PASTOMPPragma
     */
    protected void determineRegion(int type, PASTOMPPragma ompPragma)
    {
        RegionDeterminationVisitor rdv = new RegionDeterminationVisitor(type, ompPragma);
        ast_.accept(rdv);
        
        // Ensure that region for structured block is a compound statement
        if (type==STRUCTURED_BLOCK) {
            IASTNode region = ompPragma.getRegion();
            if (region==null || !(region instanceof IASTCompoundStatement))
                handleProblem("Pragma expects structured block to follow it", OpenMPError.ERROR);
        }
        else if (type==FOR_BLOCK) {
            IASTNode region = ompPragma.getRegion();
            if (region==null || !(region instanceof IASTForStatement))
                handleProblem("Pragma expects for loop to follow it", OpenMPError.ERROR);
        }
    }
    
   
    /**
     * RegionDeterminationVisitor is used to traverse AST to find region
     */
    protected class RegionDeterminationVisitor extends ASTVisitor
    {
        protected int           searchType_        = STRUCTURED_BLOCK;
        protected PASTOMPPragma oPragma_           = null; 
        protected int           pragmaLine_        = 0;
        protected int           pragmaLocation_    = 0;
        protected int           pragmaLength_      = 0;
        
        protected int           closeness_         = -1;
        
        // for statement location
        //protected IASTStatement lastStatement_ = null;
        
        public final static int STRUCTURED_BLOCK   = 0;
        public final static int FOR_BLOCK          = 1;
        public final static int EXPRESSION_BLOCK   = 2;
        public final static int LOCATION_ONLY      = 3;  // tell me what immediately precedes
        
        public RegionDeterminationVisitor(int type, PASTOMPPragma ompPragma)
        {
            searchType_ = type; 
            switch(searchType_) {
                case STRUCTURED_BLOCK:
                    shouldVisitStatements = true;
                    break;
                case FOR_BLOCK:
                    shouldVisitStatements = true;                    
                    break;
                case EXPRESSION_BLOCK:
                    shouldVisitStatements = true;    // we want an expression statement
                    break;
                case LOCATION_ONLY:
                    shouldVisitStatements = true;
                    break;
            }
            
            oPragma_        = ompPragma;
            pragmaLine_     = oPragma_.getStartingLine();
            pragmaLocation_ = oPragma_.getOffset(); //oPragma_.getStartLocation();
            pragmaLength_   = oPragma_.getLength();
        }
        
        /**
         * override function to visit statements implementation
         *         NOTE: Region is first statement following pragma
         * 
         * @param statement - IASTStatement
         * @return int
         */
        public int visit(IASTStatement statement) {
            ASTNode node = (statement instanceof ASTNode ? (ASTNode)statement : null);
            if (node==null)  return PROCESS_CONTINUE;
            
            // ensure the node is in the same file as the pragma
            if (node.getContainingFilename().equals(oPragma_.getFileLocation().getFileName())) {
              int              totalOffset = node.getOffset();
              Utility.Location loc = Utility.getLocation(node);
              assert(loc!=null);
              int localOffset = loc.getLow();  // this is the offset local to the file
              int length      = loc.getHigh()-loc.getLow()+1;
              
              // We look at all nodes that occur before the pragma - 2 cases
              // 1) if the node scope encompases the pragam, pragma is a child of node
              // 2) otherwise we call it a peer (even when it isn't)
              // Corrections occur by continuing for the tightest fit
              if (totalOffset<pragmaLocation_) {
                  if (pragmaLocation_+pragmaLength_<totalOffset+length) { // encompassing
                      oPragma_.setLocation(statement, PASTOMPPragma.ChildProximity);
                  }
                  else {
                      if (totalOffset+length<pragmaLocation_) {
                        int closeness = pragmaLocation_-(totalOffset+length);
                        if (closeness_==-1 || closeness<closeness_)   {  // get closest statement
                          oPragma_.setLocation(statement, PASTOMPPragma.NeighborProximity);
                          closeness_ = closeness;
                        }
                      }
                  }
                  // keep going to find tightest fit
              }

              // Check if this is the first node after the pragma - if so, could be our region
              if (totalOffset>pragmaLocation_) {
                if (searchType_!=LOCATION_ONLY) {
                  // With this we got to the next stmt:
                  if (searchType_==FOR_BLOCK && !(statement instanceof IASTForStatement))
                      return PROCESS_ABORT;  // error handled in determineRegion
                  // Set region information (ref. OpenMPArtifactView to see how used)
                  oPragma_.setRegionFilename(node.getContainingFilename()); 
                  oPragma_.setRegionLength(length);
                  oPragma_.setRegionOffset(localOffset);
                  oPragma_.setRegion(statement);
                  if (traceOn_)
                    System.out.println((searchType_==FOR_BLOCK ? "(for)" : "(region)") + "pragma at "+ pragmaLocation_+
                        " has statement at "+ localOffset);
                }
                return PROCESS_ABORT;
              }
            }
            return PROCESS_CONTINUE;
        }

    }

    
}
