/*
 * Scanner.java	01.07.99
 *
 *
 * Beilage zum Buch "Software-Entwurf mit UML"
 * von J.Seemann & J. Wolff von Gudenberg,
 * Springer-Verlag, 1999
 * 
 */

import java.io.*;

/** <i>Scannerobjekt f&uuml;r das Parser-Subsystem - 
       erstellt auf der Basis der Java-Bibliotheksklasse StreamTokenizer</i> 
  */

public class Scanner extends StreamTokenizer
{
   // Konstanten
   public static final int TT_PLUS =   '+';
   public static final int TT_MINUS =  '-';
   public static final int TT_MULT =   '*';
   public static final int TT_DIV =    '/';
   public static final int TT_LPAREN = '(';
   public static final int TT_RPAREN = ')';
   public static final int TT_LBRAK =  '[';
   public static final int TT_RBRAK =  ']';
   public static final int TT_ADDRESS= -10;
   public static final int TT_FUNKTION= -11;
   public static final int TT_ERROR =  0;

	 // Attribute
   double symbolWert;
   public int Symbol = TT_ERROR;

	 // Konstruktor
   public Scanner(Reader in)
   {
      super(in);
      slashSlashComments(false);
      slashStarComments(false);
      ordinaryChar('/');
      eolIsSignificant(true);
      ordinaryChar('-');
   }

	 /** pr&uuml;ft, ob der &uuml;bergebene String 
	     ein g&uuml;ltiger Funktionsname ist */
   protected boolean isFunktion(String s)
   {
      return FunktionManager.isFunktion(s);
   }

   /** pr&uuml;ft, ob der &uuml;bergebene String ein 
       g&uuml;ltiger Bereichsoperator ist (nicht benutzt)*/
   protected boolean isBereichOp(String s)
   {
      return false;
   }

   /** pr&uuml;ft, ob der &uuml;bergebene String 
       eine g&uuml;ltige Adresse ist */
   protected boolean isAdresse(String s)
   {
      char ch[] = s.toCharArray();

      if ((ch[0] >= 'a' && ch[0] <= 'z') || (ch[0] >= 'A' && ch[0] <= 'Z'))
      {
         for(int i=1; i<ch.length; i++)
         if (ch[i] < '0' || ch[i] > '9')  return false;
      }
      return true;
   }

	 /** Hauptmethode des Scanners - wird von Parser gerufen, wenn das 
	     n&auml;chste Symbol verarbeitet werden soll 
	   */
   public void nextSymbol()  
   {
      int c;
      try 
      {
         c = super.nextToken();
      }
      catch (IOException e)
      {
         c = 0;
      }
      switch (c) 
      {
         case StreamTokenizer.TT_EOF: Symbol = TT_EOF;
                                      break;
         case StreamTokenizer.TT_NUMBER: Symbol = TT_NUMBER;
                                         symbolWert = nval;
                                         break;
         case StreamTokenizer.TT_WORD: 
         {
            if (isAdresse(sval))
            {
               Symbol = TT_ADDRESS;
            }
            if (isFunktion(sval))
            {
               Symbol = TT_FUNKTION;
            }
            if (isBereichOp(sval))
            {
               Symbol = TT_ADDRESS;
            }
        }
        break;

         case '+': Symbol = TT_PLUS;
                   break;
         case '-': Symbol = TT_MINUS;
                   break;
         case '*': Symbol = TT_MULT;
                   break;
         case '/': Symbol = TT_DIV;
                   break;
         case '(': Symbol = TT_LPAREN;
                   break;
         case ')': Symbol = TT_RPAREN;
                   break;
         case '[': Symbol = TT_LBRAK;
                   break;
         case ']': Symbol = TT_RBRAK;
                   break;
         default:  Symbol = TT_ERROR;
      }
   }
}
