package osa.attribute.atgrammar.grammar.symbols;


import java.util.*;
import java.lang.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * @author not attributable
 * @version
 */

public class LexicalScanner
  {
  protected class AutomatonState
    {
    protected String name;
    protected ArrayList transitions=new ArrayList();
    protected boolean is_final;

    public AutomatonState(String name, boolean is_final)
      {
      this.name=name;
      this.is_final=is_final;
      }

    public void addTransition(AutomatonTransition transition)
      {
      transitions.add(transition);
      }

    public AutomatonTransition getTransitionAt(int index)
      {
      if(index>getTransitionsCount()||index<0)
        {
        System.err.println("Out of bounds!!!");
        return null;
        }
      return (AutomatonTransition)transitions.get(index);
      }

    public int getTransitionsCount()
      {
      return transitions.size();
      }
    }

  protected class AutomatonTransition
    {
    protected AutomatonState target_state;
    protected char input_symbol;
    protected char output_symbol;
    protected boolean is_shifting;

    public AutomatonTransition(AutomatonState target_state,
                               char input_symbol,
                               char output_symbol,
                               boolean is_shifting)
      {
      this.target_state=target_state;
      this.input_symbol=input_symbol;
      this.output_symbol=output_symbol;
      this.is_shifting=is_shifting;
      }

    public AutomatonState getTargetState()
      {
      return target_state;
      }

    public char getInputSymbol()
      {
      return input_symbol;
      }

    public boolean isShifting()
      {
      return is_shifting;
      }
    }

  protected class StringReader
    {
    protected String input_string;
    protected int position;
    protected int string_length;

    public StringReader(String input_string)
      {
      this.input_string=input_string;
      this.position=0;
      this.string_length=input_string.length();
      }

    public int getPosition()
      {
      return position;
      }

    public void setPosition(int position)
      {
      this.position=position;
      }

    public String getInputString()
      {
      return input_string;
      }

    public void setInputString(String input_string)
      {
      this.input_string=input_string;
      this.position=0;
      this.string_length=input_string.length();
      }


    protected char getCurrentChar()
      {
      if(position<this.string_length)
        {
        return input_string.charAt(position);
        }
      return 0;
      }

    protected char getNextChar()
        {
        position++;
        if(position<this.string_length)
          {
          return input_string.charAt(position);
          }
        return 0;
        }

    protected char lookForward()
      {
      if((position+1)<this.string_length)
        {
        return input_string.charAt(position+1);
        }
      return 0;
      }


    protected void needParseString()
      {
      moveToToken();

      char c=getCurrentChar();
      switch(c)
            {
            case '*':
              needTransition(true);
              break;
            case '(':
              needTransition(false);
              break;
            case '-':
              needComment();
            default:
            }
      }


    protected void needTransition(boolean is_shifting)
      {
      String source_state_name;
      String target_state_name;
      char input_symbol;
      char output_symbol;

      // левая часть функции перехода

      // левая скобка
      needLeftParenthesis();

      // исходное состояние
      source_state_name=needName();

      // запятая
      needComma();

      // передвигаемся к следующей лексеме
      moveToToken();

      // апостроф
      needApostrophe();

      // входной символ
      input_symbol=getNextChar();

      // апостроф
      needApostrophe();

      // правая скобка
      needRightParenthesis();


      // символ :-
      needTransitionSymbol();

      // левая скобка
      needLeftParenthesis();

      // целевое состояние

      // если обнаружена кавычка, то это переход в конечное состояние
      // с генерацией терминала, являющегося
      moveToToken();

      if(lookForward()=='"')
        {

        }
      else
        {
        target_state_name=needName();

        // если запятая не обнаружена, то это "холостой переход"
        // т.е. выходной символ не генерируется

        moveToToken();
        if(this.lookForward() ==',')
          {
          getNextChar();
          moveToToken();

        needQuotationMark();



        needQuotationMark();
        }




      // правая скобка
      needRightParenthesis();
      }


    protected void needComment()
      {
      if(getNextChar()!='-')
        {
        // throw
        }
      }

    protected boolean needLeftParenthesis()
      {
      moveToToken();

      if(getNextChar()=='(')
        {
        return true;
        }
      return false;
      }

    protected boolean needRightParenthesis()
      {
      moveToToken();

      if(getNextChar()==')')
        {
        return true;
        }
      return false;
      }

    protected boolean needComma()
      {
      moveToToken();
      if(getNextChar()==',')
        {
        return true;
        }
      return false;
      }

    protected boolean needQuotationMark()
      {
      if(getNextChar()=='"')
        {
        return true;
        }
      return false;
      }

    protected boolean needApostrophe()
      {
      if(getNextChar()=='\'')
        {
        return true;
        }
      return false;
      }

    protected String needName()
      {
      StringBuffer buffer=new StringBuffer();
      moveToToken();

      char c;
      c=getNextChar();

      if(Character.isJavaIdentifierPart(c))
        {
        while(Character.isJavaIdentifierPart(c))
             {
             buffer.append(c);
             }
        }
      else
        {
        //throw
        }
      return buffer.toString();
      }

    protected String needString()
      {
      StringBuffer buffer=new StringBuffer();

      char c;


      c=getNextChar();

      boolean condition=true;

      while(condition)
           {
           switch(c)
                 {
                 case '\\':
                   char next_to_bkslash=getNextChar();
                   switch(next_to_bkslash)
                         {
                         case '"':
                         buffer.append('"');
                         break;
                         case '\\':
                         buffer.append('\\');
                         break;
                         default:
                         // throw
                         }
                   break;
                 case '"':
                   condition=false;
                   break;
                 default:
                   buffer.append(c);
                 }
           }
      return buffer.toString();
      }

    protected void needTransitionSymbol()
      {
      moveToToken();

      if(getNextChar()!=':')
        {
        //throw
        }
      if(getNextChar()!='-')
        {
        //throw
        }
      }

    protected boolean isCharIsDelimiter(char c)
      {
      return Character.isWhitespace(c);
      }

    protected void moveToToken()
      {
      char c=lookForward();
      while(isCharIsDelimiter(c))
           {
           getNextChar();
           c=lookForward();
           }
      }

    }

  protected class ScannerException
    extends Exception
    {
    protected int error_position;

    public ScannerException(String message, int error_position)
      {
      super(message);
      this.error_position=error_position;
      }
    public int getErrorPosition()
      {
      return error_position;
      }
    }


  protected String textual_representation;
  protected AutomatonState start_state;
  protected TreeMap automaton_states;

  protected StringReader current_reader;

  protected StringBuffer buffer;

  public LexicalScanner()
    {
    }



  }