/*********************************************************************
 *
 *      ***  HAPPy Pascal compiler ***
 *          input symbol routine
 *
 *               void insymbol(void)
 *               void real_err(int sig, int subcode)
 *
 *            copyright(c) H.Asano  1992-1994.
 *
 *              return item -----
 *                sy   : 要素のsymbol
 *                op   : 要素の演算子タイプ
 *                id   : 名標
 *                ch   : 読込文字
 *                lgth : 文字列等の長さ
 *                val  : 数値
 *
 *********************************************************************/

#define EXTERN extern

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <jctype.h>
#include "pascomp.h"
#include "pcpcd.h"

/***** function prototype define ******/

extern void gen1(enum pcdmnc, int) ;
extern void pcerr(int,char*);
extern char *inttoch(long)  ;
extern void term(void) ;
extern void *Malloc(int) ;
static void skipspace(void);
static void nextch(void);
static void identifier(void);
static void innumber(void) ;
static long chtoint(int,char*) ;
static void strings(void) ;
static void colonch(void);
static void lparch(void);
static void rparch(void);
static void periodch(void);
static void ltch(void);
static void gtch(void);
static void skipcomment(void);
static void options(void)  ;
static void specialch(void);
static void illegch(void);


/*****************************/
/****      共通変数       ****/
/*****************************/

extern FILE   *passource;  /* pascal ソースファイルポインタ */

/*****************************/
/****      内部変数       ****/
/*****************************/


/***** pascal 予約語テーブル *****/
static struct _reswd {
       char          rw[10] ;           /* 予約語           */
       enum symbol   rsy   ;            /* 予約語のsymbol   */
       enum operator rop   ;            /* 予約語中の演算子 */
    }  reswd[]  =     {
/*lngh entno  (for frw table) */
/*  2 *   0 */  {"if"       , ifsy     , noop },
/*    *   1 */  {"do"       , dosy     , noop },
/*    *   2 */  {"of"       , ofsy     , noop },
/*    *   3 */  {"to"       , tosy     , noop },
/*    *   4 */  {"in"       , relop    , inop },
/*    *   5 */  {"or"       , addop    , orop },
/*  3 *   6 */  {"end"      , endsy    , noop },
/*    *   7 */  {"for"      , forsy    , noop },
/*    *   8 */  {"var"      , varsy    , noop },
/*    *   9 */  {"div"      , mulop    , idiv },
/*    *  10 */  {"mod"      , mulop    , imod },
/*    *  11 */  {"set"      , setsy    , noop },
/*    *  12 */  {"and"      , mulop    , andop},
/*    *  13 */  {"not"      , notsy    , noop },
/*    *  14 */  {"nil"      , nilsy    , noop },
/*  4 *  15 */  {"then"     , thensy   , noop },
/*    *  16 */  {"else"     , elsesy   , noop },
/*    *  17 */  {"with"     , withsy   , noop },
/*    *  18 */  {"goto"     , gotosy   , noop },
/*    *  19 */  {"case"     , casesy   , noop },
/*    *  20 */  {"type"     , typesy   , noop },
/*    *  21 */  {"file"     , filesy   , noop },
/*  5 *  22 */  {"begin"    , beginsy  , noop },
/*    *  23 */  {"until"    , untilsy  , noop },
/*    *  24 */  {"while"    , whilesy  , noop },
/*    *  25 */  {"array"    , arraysy  , noop },
/*    *  26 */  {"const"    , constsy  , noop },
/*    *  27 */  {"label"    , labelsy  , noop },
/*  6 *  28 */  {"repeat"   , repeatsy , noop },
/*    *  29 */  {"record"   , recordsy , noop },
/*    *  30 */  {"downto"   , downtosy , noop },
/*    *  31 */  {"packed"   , packedsy , noop },
/*  7 *  32 */  {"program"  , progsy   , noop },
/*  8 *  33 */  {"function" , funcsy   , noop },
/*  9 *  34 */  {"procedure", procsy   , noop }
} ;

static int frw[] = {0,0,6,15,22,28,32,33,34,35,35};
    /*  予約語の長さで､予約語テーブルのサーチを高速化している */

/***** 読込み対象JISコード256種類を分類するためのテーブル *****/

enum  chtp {
      letter,     /* 英字             */
      number,     /* 数字             */
      special,    /* 特殊文字         */
      illegal,    /* 許されないコード */
      chstrquo,   /* コーテーション   */
      chcolon,    /* :  コロン        */
      chperiod,   /* . ピリオド       */
      chlt,       /* <  less than     */
      chgt,       /* >  grater than   */
      chlparen,   /* (  左かっこ      */
      chrparen,   /* )  右かっこ      */
      chcoment,   /* {  注釈開始      */
      chspace     /* 空白             */
} ;
static struct  {
       enum chtp     chartp    ;      /* 文字のタイプ  */
       enum symbol   ssy       ;      /* 文字のsymbol  */
       enum operator sop       ;      /* 文字中の演算子*/
    }  chartb[256]  =    {

 /****** 00-1F : 制御コード  HT(09),LF(0A)はspace  それ以外はillegal *******/
 /*00-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*03-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*06-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*09-*/{chspace,othersy,noop}, {chspace,othersy,noop}, {illegal,othersy,noop},
 /*0C-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*0F-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*12-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*15-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*18-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*1B-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*1E-*/{illegal,othersy,noop}, {illegal,othersy,noop},

   /****** 20-2F : 各種文字 ******/
 /* sp  (20) */    {chspace,othersy,noop},
 /* !   (21) */    {illegal,othersy,noop},
 /* "   (22) */    {illegal,othersy,noop},
 /* #   (23) */    {illegal,othersy,noop},
 /* $   (24) */    {special,othersy,noop},
 /* %   (25) */    {illegal,othersy,noop},
 /* &   (26) */    {illegal,othersy,noop},
 /* '   (27) */    {chstrquo,othersy,noop},
 /* (   (28) */    {chlparen,lparent,noop},
 /* )   (29) */    {chrparen,rparent,noop},
 /* *   (2A) */    {special,mulop,mul},
 /* +   (2B) */    {special,addop,plus},
 /* ,   (2C) */    {special,comma,noop},
 /* -   (2D) */    {special,addop,minus},
 /* .   (2E) */    {chperiod,period,noop},
 /* /   (2F) */    {special,mulop,rdiv},

   /****** 30-39: 数字 ******/
 /*012*/ {number,othersy,noop}, {number,othersy,noop}, {number,othersy,noop},
 /*345*/ {number,othersy,noop}, {number,othersy,noop}, {number,othersy,noop},
 /*678*/ {number,othersy,noop}, {number,othersy,noop}, {number,othersy,noop},
 /*9  */ {number,othersy,noop},

   /****** 3A-40 : 各種文字 ******/
 /* :   (3A) */    {chcolon,colon,noop},
 /* ;   (3B) */    {special,semicolon,noop},
 /* <   (3C) */    {chlt,relop,ltop},
 /* =   (3D) */    {special,relop,eqop},
 /* >   (3E) */    {chgt,relop,gtop},
 /* ?   (3F) */    {illegal,othersy,noop},
 /* @   (40) */    {special,arrow,noop},  /* ^ の 代用 */

   /****** 41-5A : 英大文字 ******/
 /*ABC*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*DEF*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*GHI*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*JKL*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*MNO*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*PQR*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*STU*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*VWX*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*YZ */ {letter,othersy,noop}, {letter,othersy,noop},

   /****** 5B-60 : 各種文字 ******/
 /* [   (5B) */    {special,lbrack,noop},
 /* \   (5C) */    {illegal,othersy,noop},
 /* ]   (5D) */    {special,rbrack,noop},
 /* ^   (5E) */    {special,arrow,noop},
 /* _   (5F) */    {illegal,othersy,noop},
 /* `   (60) */    {illegal,othersy,noop},

  /****** 61-7A : 英小文字 ******/
 /*abc*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*def*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*ghi*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*jkl*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*mno*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*pqr*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*stu*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*vwx*/ {letter,othersy,noop}, {letter,othersy,noop}, {letter,othersy,noop},
 /*yz */ {letter,othersy,noop}, {letter,othersy,noop},

   /****** 7B-7F : 各種文字 ******/
 /* {   (7B) */    {chcoment,othersy,noop},
 /* |   (7C) */    {illegal, othersy,noop},
 /* }   (7D) */    {illegal, othersy,noop},
 /*(7E-7F)*/       {illegal, othersy,noop}, {illegal,othersy,noop},

   /***** 80-FF : 各種記号 & カタカナ ******/
 /*80-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*83-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*86-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*89-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*8C-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*8F-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*92-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*95-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*98-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*9B-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*9E-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*A1-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*A4-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*A7-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*AA-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*AD-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*B0-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*B3-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*B6-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*B9-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*BC-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*BF-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*C2-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*C5-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*C8-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*CB-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*CE-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*D1-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*D4-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*D7-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*DA-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*DD-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*E0-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*E3-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*E6-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*E9-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*EC-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*EF-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*F2-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*F5-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*F8-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*FB-*/{illegal,othersy,noop}, {illegal,othersy,noop}, {illegal,othersy,noop},
 /*FE-*/{illegal,othersy,noop}, {illegal,othersy,noop}
 };

static boolean eolnflag    = true  ;    /* EOLN検出時 true            */
static boolean period2flag = false ;    /* 数字処理中 ".." 検出時 true*/
static boolean rbrackflag  = false ;    /* 数字処理中 ".)" 検出時 true*/

/*************************************************************************/

/**************************************/
/*   insymbol() : symbolの読込メイン  */
/**************************************/

void insymbol(void)
{
     skipspace() ;                      /* 空白読み飛ばし             */
     switch(chartb[ch].chartp) {
       case letter  : identifier()  ;  break; /* 名前の  処理         */
       case number  : innumber()    ;  break; /* 数字の  処理         */
       case chstrquo: strings()     ;  break; /* 文字列  処理         */
       case chcolon : colonch()     ;  break; /* : の    処理         */
       case chperiod: periodch()    ;  break; /* . の    処理         */
       case chlt    : ltch()        ;  break; /* < の    処理         */
       case chgt    : gtch()        ;  break; /* > の    処理         */
       case chlparen: lparch()      ;  break; /* ( の    処理         */
       case chrparen: rparch()      ;  break; /* ) の    処理         */
       case chcoment: skipcomment() ;  break; /* 注釈の  処理         */
       case special : specialch()   ;  break; /* 特殊文字処理         */
       case illegal : illegch()     ;  break; /* 不当文字処理         */
    /* case chspace :                   ---> このcase分岐はあり得ない */
     };
}

/**************************************/
/*  skipspace() : 空白読み飛ばし      */
/**************************************/
static void skipspace(void)
{
     while(chartb[ch].chartp == chspace)
      nextch();
}

/**************************************/
/*    nextch() : 次の1字読込処理      */
/**************************************/
static void nextch(void)
{
  static boolean eofflag  = false ;     /* EOF検出時  true            */
  int lch ;

     if(eofflag) {
      pcerr(610,"") ;                   /* EOF検出                    */
      term() ;                          /* 終了処理                   */
     }

     if(eolnflag) {                    /* 前の文字が行の終わりだった時*/
      lineno++;
      do ;
       while((lch=getc(passource)) == ' '); /* 空白読み飛ばし         */
     }

     if(!eolnflag) lch = getc(passource) ;

     eofflag  = feof(passource) ;
     eolnflag = (lch == '\n') ;
     ch = (eofflag)                     /* EOFの時は  読込文字を空白  */
           ? ' ' : lch ;

}

/**************************************/
/*     identifier() : 名前の処理      */
/**************************************/
static void identifier(void)
{
  int k=0;
  int i;
  enum chtp wktype ;

     for(i=0;i<=MaxIDlng;i++)          /* null クリア                */
      id[i]='\0';
                             /***** 高速化のためにポインタを使う  *****/
     do {
      if(k<MaxIDlng)                    /* 最大識別長まで格納         */
       *(id+k++)=(('A'<=ch) && (ch<='Z'))  ? (char)ch+' ' : (char)ch ;
                                        /* 大文字を小文字に変換       */
      nextch();
      } while(((wktype=(*(chartb+ch)).chartp) == letter) ||
	      ( wktype                        == number)) ;

      for(i=*(frw+k-1); i<*(frw+k);i++) { /* 予約語テーブルサーチ     */
       if(!strcmp(id,(*(reswd+i)).rw)) {  /* 予約語である時           */
	sy = (*(reswd+i)).rsy ;           /* 対応したsymbolを返す     */
        op = (*(reswd+i)).rop ;
        return;
       }
      }
      sy = ident;                       /* 予約語以外の時は、ident    */
      op = noop;
}

/**************************************/
/*     innumber() : 数字の処理        */
/**************************************/
static void innumber(void)
{
  char digit[Maxdiglng+1];
  csp *lvp ;
  int k=0  ;
  int w   ;
  float realvalue ;
  char *stopstring ;

     op = noop ;

     for(w=0;w<=Maxdiglng;w++)          /* null クリア                */
      digit[w]='\0';

     do {
      if(k < Maxdiglng) digit[k] = (char)ch ;/* 最大数字長以下の時格納*/
      k++ ;
      nextch() ;
     } while(chartb[ch].chartp == number) ;

     if((ch != '.') && (ch != 'e') && (ch != 'E')){ /* real型でない時 */
      val.ival =chtoint(k,digit) ;      /*  整数値に変換              */
      return ;
     }

     if(ch == '.') {                    /* 小数点の時                 */
      if(k < Maxdiglng) digit[k]=(char)ch;/* 最大数字長以下の時格納   */
      k++ ;
      nextch() ;
      period2flag = (ch == '.') ;       /* ".."                       */
      rbrackflag  = (ch == ')') ;       /* ".)"  ] の代替表現         */
      if(period2flag || rbrackflag) {   /* ".." または ".)" の時      */
       val.ival =chtoint(k-1,digit) ;   /*  整数値に変換              */
       return ;
      }
      if(chartb[ch].chartp != number)   /* .の次の文字が数字以外      */
       pcerr(201,"") ;                  /* 実数の表記に誤りがある     */
      else {
       do {
        if(k < Maxdiglng) digit[k] = (char)ch ;
        k++ ;
        nextch() ;
       } while(chartb[ch].chartp == number) ;
      }
     }

     if((ch == 'e') || (ch == 'E')) {   /* eの時                      */
      if(k < Maxdiglng) digit[k]=(char)ch;/* 最大数字長以下の時格納   */
      k++ ;
      nextch() ;
      if((ch=='+') || (ch=='-')) {      /* e の次が+ - の時           */
       if(k < Maxdiglng) digit[k]=(char)ch;/* 最大数字長以下の時格納  */
       k++ ;
       nextch() ;
      }
      if(chartb[ch].chartp != number)
       pcerr(201,"") ;                  /* 実数の表記に誤り           */
      else
       do {
        if(k < Maxdiglng) digit[k] = (char)ch ;
        k++ ;
        nextch() ;
       } while(chartb[ch].chartp == number) ;
     }

     if(k > Maxdiglng) {
      pcerr(207,inttoch((long)Maxdiglng));/*数の桁数が範囲を越えている*/
      strcpy(digit,"0.0");              /*  0.0 とする                */
     }

     sy = realconst ;
     lvp = (csp*)Malloc(sizeof(csp)) ;
     lvp->cclass = real ;
     val.valp = lvp ;                   /* 実数型の定数アドレスを設定 */
     lvp->c.rval = (char*)Malloc(k+2);  /* 符号分､nullの2バイト分余分に確保*/
     *(lvp->c.rval) = ' ' ;             /* 先頭は符号エリア           */
     strcpy(lvp->c.rval+1,digit) ;      /* 転送                       */
     realvalue = (float)strtod(lvp->c.rval, &stopstring) ;
      /* 実数変換エラーが起きるか判定 エラーとなればsignalで登録した
         エラー処理関数に飛んでいく     */
}

/*****************************************/
/* real_err() : 実数変換エラーの時の処理 */
/*  init内のsignal関数で登録される       */
/*****************************************/
void real_err(int sig, int subcode)
{
     pcerr(208,"") ;
}

/*****************************************/
/* chtoint() : 文字から整数への変換処理  */
/*****************************************/
static long chtoint(int i,char *digit)
{
  long value = 0 ;
  int j ;

     sy = intconst ;                    /* 整数とする                 */
     if(i > Maxdiglng) {
      pcerr(207,inttoch((long)Maxdiglng));/*数の桁数が範囲を越えている*/
      return(0L) ;
     }
     for(j=0;j<i;j++)                   /* 文字を整数に変換           */
      if(value <= (Maxint - (digit[j]-'0')) / 10  ) /* 上限チェック   */
       value = value*10 + (digit[j]-'0') ;
      else {
       pcerr(203,inttoch(Maxint)) ;     /* 符号なし整数がmaxintより大きい*/
       return(0L)        ;
      }
     return(value) ;
}

/**************************************/
/*     strings() : 文字列の処理       */
/**************************************/
static void strings(void)
{
  char string[Maxstrlng+1] ;
  char *heapstring ;

     lgth = 0 ;
     sy   = stringconst ;
     op   = noop ;

     do {
      do {
       nextch() ;
       if(lgth<Maxstrlng) string[lgth]=(char)ch;/* 最大文字列長以下の時格納 */
       lgth++ ;
      } while((!eolnflag) && (ch != '\'')) ;
      if(eolnflag) pcerr(202,"") ;      /* 文字列定数は行を越えてはならない */
      else nextch() ;                   /* 'の時､次の文字を読む             */
     } while(ch == '\'') ;              /* 'が2続くときはもう一度繰り返す   */

     lgth-- ;                           /* 最後の'を取り除く                */
     if(lgth==0) pcerr(205,"") ;        /* 文字長0の文字列は許されない      */
     else if(lgth == 1)
      val.ival = (long)string[0];       /* 1文字の時は、その値をvalに入れる */
     else {                             /* 2文字以上の時                    */
      val.valp = (csp*)Malloc(sizeof(csp)) ;
      val.valp->cclass = strg ;
      if(lgth > Maxstrlng) {            /* 最大文字列長を越えている時       */
       pcerr(602,inttoch((long)Maxstrlng)) ; /* 文字列の最大長を越えている  */
       lgth = Maxstrlng ;               /* 最大文字列長までを有効とする     */
      }
      string[lgth] = '\0' ;             /* nullで終わる文字列とする         */
      heapstring = (char*)Malloc(lgth+1) ;/* 文字列長分のエリアを確保       */
      strcpy(heapstring,string) ;
      val.valp->c.sval = heapstring ;
     }
}

/**************************************/
/*     colonch() : :(ｺﾛﾝ) の処理      */
/**************************************/
static void colonch(void)
{
     op = noop;
     nextch();
     if(ch == '=') {                    /* ':='                       */
      sy = becomes;                     /*   becomes  と する         */
      nextch();
     }
     else sy = colon ;                  /* ':'  colon と する         */
}

/**************************************/
/*     lparch() : ( の処理            */
/**************************************/
static void lparch(void)
{
     op = noop   ;
     nextch();
     if(ch == '*') skipcomment();       /* '(*'   注釈                */
     else if(ch == '.') {               /* '(.'   [ の代替表現        */
      nextch()    ;
      sy = lbrack ;
     }
     else  sy = lparent;
}

/**************************************/
/*     rparch() : ) の処理            */
/**************************************/
static void rparch(void)
{
     op = noop;
     nextch();
     if(rbrackflag) {                   /* 数字処理中 ".)"を見つけた時*/
      sy = rbrack  ;                    /* 数字処理中 .. を見つけた時 */
      rbrackflag = false ;
     }
     else sy = rparent;
}

/*******************************************/
/* skipcomment() : コメントの読み飛ばし処理*/
/*    *) または } がコメントの終わり       */
/*        ただし } は、シフトJISの2バイト目*/
/*          になり得るので、その処理もする */
/*******************************************/
static void skipcomment(void)
{
  boolean endflag ;

     nextch();
     if(ch=='$') options();             /* $の後にはｵﾌﾟｼｮﾝ が来る     */
     do {
      while(iskanji(ch)) {              /* ｼﾌﾄJIS1ｺｰﾄﾞ1バイト目の時   */
       nextch() ;                       /* 2文字分読み飛ばし          */
       nextch() ;
      }
      if(ch=='*') {
       nextch() ;
       endflag=((ch==')')||(ch=='}')) ; /*   *) または　}             */
      }
      else {
       endflag = (ch == '}') ;          /*   }  でコメント終わり      */
       if(!endflag) nextch() ;
      }
     } while(!endflag) ;
     nextch()  ;
     insymbol();                        /* 有効なsymbolを見つける(再帰)*/
}

/*****************************************/
/* options() : オプション設定処理        */
/*             d+ d- t+ t-               */
/*****************************************/
static void options(void)
{
  char optionchar ;

     nextch() ;
     optionchar = (char)ch ;
     if((ch=='d') || (ch=='t')) nextch();
     else return ;
     if((ch=='+') || (ch=='-'))
      if(optionchar=='d') debug = (ch=='+') ;
      else
       if(ch=='+') gen1(iTRA,1) ;       /* トレースオン  tra  1       */
       else        gen1(iTRA,2) ;       /* トレースオフ  tra  2       */
}

/****************************************/
/* periodch() :  .(ﾋﾟﾘｵﾄﾞ)の処理        */
/****************************************/
static void periodch(void)
{
     op = noop;
     nextch();
     if(period2flag) {
      sy = period2 ;                    /* 数字処理中 .. を見つけた時 */
      period2flag = false ;
     }
     else if(ch == '.') {               /* 今 .. だった時             */
       sy = period2 ;                   /* ..  と する                */
       nextch();
     }
     else if(ch == ')') {               /* 今 .) だった時             */
      sy = rbrack ;                     /*  ]   とする                */
      nextch()    ;
     }
     else sy = period ;                 /* . 単独の時は . とする      */
}

/****************************************/
/*        ltch() :  < の処理            */
/****************************************/
static void ltch(void)
{
     nextch();
     sy=relop;
     if(ch == '=') {                    /* '<='                       */
      op = leop;                        /*       less equal と する   */
      nextch();
     }
     else if(ch == '>') {               /* '<>'                       */
      op = neop ;                       /*       not equal  と する   */
      nextch()  ;
     }
     else op = ltop ;                   /* '<'   less than とする     */
}

/****************************************/
/*        gtch() :  > の処理            */
/****************************************/
static void gtch(void)
{
     nextch();
     sy = relop;
     if(ch == '=') {                    /* '>='                       */
      op = geop;                        /*   grater equal と する     */
      nextch();
     }
     else op = gtop ;                   /* '>'  grater than とする    */
}

/****************************************/
/*      specialtch() : 特殊文字の処理   */
/****************************************/
static void specialch(void)
{
     sy = chartb[ch].ssy ;              /* その文字のsymbol           */
     op = chartb[ch].sop ;              /* その文字の演算子           */
     nextch()            ;
}

/****************************************/
/*        illegch() : 不当文字の処理    */
/****************************************/
static void illegch(void)
{
  char wch[3] ;

     sy = othersy;
     op = noop   ;
     wch[0] = (char)ch ;
     if(iskanji(ch)) {                  /* 漢字の時 漢字埋め込み処理  */
      nextch() ;
      wch[1] = (char)ch   ;
      wch[2] = '\0' ;
     }
     else wch[1] = '\0' ;
     pcerr(30,wch)      ;               /* 不当文字が現れた           */
     nextch()           ;
}
