#include <stdio.h>   /*   **************  formck.c  ************** */
#include <string.h>
/* #include <process.h> */       /*    for MS-C && TURBO C++  */
/*      #include <stdlib.h>  ;  for Lattice C */
#include <ctype.h>
#include "macro.h"
#include "jehonfnc.h"

#define  USER


static int  hdTlCk(char ptek[], int ln);
static void condFormcheck(char ptek[]);
static void JFormcheck(char ptek[]);
static void EFormcheck(char ptek[]);
static void FormAlert(char ptek[], char *ptc, char *pt2);
static int  bunHdTlCk(int ln);
static void bCondFormcheck(void);
static void bJFormcheck(void);
static void bEFormcheck(void);
static void bFormAlert(char *ptc, char *pt2, int chk);

#include "honyavar.h"


void  tekFormcheck(char ptek[]) /* 適訳規則の書式をチェックする。*/
begin
   int  ln, chk;
   char qptek[160], rem[2][5] = {"先頭","末尾"};
   char *ptc, errPart[WordLen];

   ln = strlen(ptek);
   while ((*(ptek + ln - 1) == '\n') || (*(ptek + ln - 1) == ' ')) {
   _  *(ptek + ln - 1) = '\0';
   _  --ln;
   }
   chk = 2;
   if (ptek == strstr(ptek,"***")) {
   _  if (strcmp(ptek + ln - 3,"***"))
   _     chk = 1;
   }
   else {
   _  ptc = strstr(ptek,"  ");
   _  if (ptc) {
   _  _  beeping(2);
   _  _  color_red;
   _  _  printf("\n\n 適訳規則に余分な空白があります。エディターを使って削除して下さい。\n");
   _  _  color_white;
   _  _  ptcpy(qptek,ptek,ptc - 1);
   _  _  ptcpy(errPart,ptc - 1,ptc + 3);
   _  _  printf(" 適訳規則 = ");
   _  _  color_light_blue;
   _  _  printf("%s",qptek);
   _  _  color_yellow;
   _  _  printf("%s",errPart);
   _  _  color_light_blue;
   _  _  printf("%s",ptc + 3);
   _  _  exit(1);
   _  }
   _  if (((! isdigit(*ptek)) && (*ptek != 'X')) || ((! isdigit(*(ptek + 1))) && (*(ptek + 1) != 'X')) || (*(ptek + 2) != ';'))
   _     chk = 0;
   _  else
   _     if ((ln < 7) || (*(ptek + ln - 1) != ';') || (*(ptek + ln - 6) != ' '))
   _        chk = 1;
   _  if (chk == 2)
   _     chk = hdTlCk(ptek,ln); /* 適訳規則 ptek[] の先頭と末尾の書式のチェック */ 
   }
   if (chk < 2) {
   _  beeping(2);
   _  if (ln < 20)
   _  _  strcpy(qptek,ptek);
   _  else {
   _  _  ptcpy(qptek,ptek,ptek + 8);
   _  _  strcat(qptek,".....");
   _  _  strcat(qptek,ptek + ln - 7);
   _  }
   _  color_red;
   _  printf("\n\n 適訳規則の%sの部分が書式に合致していません。エディターで訂正して下さい！！ \n",rem[chk]);
   _  color_white;
   _  printf(" 適訳規則 = ");
   _  color_yellow;
   _  printf("%s \n\n",qptek);
   _  color_white;
   _  exit(1);
   }
   ptc = strstr(ptek,";;");
   if (ptc) {
   _  beeping(2);
   _  color_red;
   _  printf("\n\n 適訳規則に空白欄があります。エディターを使って削除して下さい。\n");
   _  color_white;
   _  ptcpy(qptek,ptek,ptc);
   _  ptcpy(errPart,ptc,ptc + 2);
   _  printf(" 適訳規則 = ");
   _  color_light_blue;
   _  printf("%s",qptek);
   _  color_yellow;
   _  printf("%s",errPart);
   _  color_light_blue;
   _  printf("%s",ptc + 2);
   _  exit(1);
   }
   condFormcheck(ptek);        /* 適訳条件の書式をチェックする。*/
end

static int  hdTlCk(char ptek[], int ln)  /* 適訳規則 ptek[] の先頭と末尾の書式のチェック */
begin  /* global variable: ptek[] */
   int  chk = 2;
   char *pt1, *pt2, zokusei2[3];

   pt1 = ptek + 3;
   if (*pt1 == '*')
      ++pt1;
   if (*(pt1 + 1) == ';') {
   _  pt2 = pt1 + 2;
   _  if (*(pt2 + 1) != ';')
   _     chk = 0;
   _  else {
   _  _ switch(*pt2) {
   _  _   case '0':
   _  _     if ((! isdigit(*pt1)) && (*pt1 != 'X'))
   _  _        chk = 0;
   _  _     break;
   _  _   case '1':
   _  _     if ((! isalpha(*pt1)) && (! strchr("<$!",*pt1)))
   _  _        chk = 0;  /* '<' を加えた。2000.11.15 */
   _  _     break;
   _  _   case '2':
   _  _     if (isdigit(*pt1) || isalpha(*pt1))
   _  _        chk = 0;
   _  _     break;
   _  _   case '3':
   _  _     break;
   _  _   default:
   _  _     chk = 0;
   _  _  }
   _  }
   }
   else {
   _  pt2 = strchr(pt1 + 2,';');
   _  ++pt2;
   _  if ((*pt2 != '2') || (*(pt2 + 1) != ';')) {
   _  _  if (*pt2 == '3') {
   _  _  _  ptcpy(zokusei2,pt1,pt1 + 2);
   _  _  _  if (! strstr("序全位の",zokusei2))  /* 「位」を追加した。2000.11.12 */
   _  _  _     chk = 0;                         /* 「の」を追加した。2002.11.04 */
   _  _  }
   _  _  else
   _  _     chk = 0;
   _  }
   }
   if (chk == 2) {
   _  pt1 = ptek + ln - 7;
   _  if ((*pt1++ != ';') || ((! isdigit(*(++pt1))) && ((*pt1 < 'A') || (*pt1 > 'z') || ((*pt1 > 'Z') && (*pt1 < 'a')))) || (! isdigit(*(++pt1))) || (! isdigit(*(++pt1))) || (! isdigit(*(++pt1))))
   _     chk = 1;
   }
   return(chk);
end

static void condFormcheck(char ptek[]) /* 適訳条件の書式をチェックする。*/
begin
   int  chk;
   char *ptc, *pt2;

   JFormcheck(ptek);
   chk = 2;
   ptc = strstr(ptek,";T");
   while(ptc) {
   _  pt2 = ptc + 2;
   _  if (*pt2 == '-')
   _     ++pt2;
   _  if (isdigit(*pt2) || strchr("AZ#",*pt2)) {
   _  _  if (*(++pt2) == '<')
   _  _     ++pt2;
   _  _  if ((*pt2 == '=') || (*pt2 == '>')) {
   _  _  _  if (isalpha(*(++pt2)) || strchr("?R$<&",*pt2))
   _  _  _     ptc = pt2;
   _  _  _  else {
   _  _  _  _  chk = 0;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  _  else {
   _  _  _  chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  else {
   _  _  chk = 0;
   _  _  break;
   _  }
   _  ptc = strstr(ptc,";T");
   }
   if (chk)
      EFormcheck(ptek);
		       /* 英単語 en[] に関する適用条件の書式をチェックする。*/
   if (chk) {
   _  ptc = strstr(ptek,";D");
   _  while(ptc) { /* 倍角文字列に関する条件書式チェック */
   _  _  pt2 = ptc + 2;
   _  _  if (strchr("DIJ",*pt2))
   _  _     ++pt2;           /* Dn = ".." および DIn/DJn/DDn = "...."  */
   _  _  if (*pt2 == '-')
   _  _     ++pt2;
   _  _  if (isdigit(*pt2) || strchr("AZ#",*pt2)) {
   _  _  _  if (*(++pt2) == '<')
   _  _  _     ++pt2;
   _  _  _  if ((*pt2 == '=') || (*pt2 == '>'))
   _  _  _     ptc = pt2;
   _  _  _  else {
   _  _  _  _  chk = 0;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  _  else {  /* ptc = ";DF2J=...." の場合 */
   _  _  _  if ((*pt2 == 'F') && (*(pt2 + 1) == '2') && (*(pt2 + 2) == 'J')) {
   _  _  _  _  pt2 += 3;
   _  _  _  _  if ((*pt2 == '=') || ((*pt2 == '<') && (*(pt2 + 1) == '>')))
   _  _  _  _     ptc = pt2;
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  _  else {
   _  _  _  _  chk = 0;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  _  ptc = strstr(ptc,";D");
   _  }
   }
   if (! chk)
      FormAlert(ptek,ptc,pt2);     /* 適訳条件書式の違反を警告する。*/
end

static void JFormcheck(char ptek[]) /* 日本語訳語に関する条件の書式をチェックする。*/
begin   /* global variable: ptek[] */
   int  chk;
   char *ptc, *pt2;

   chk = 2;
   ptc = strstr(ptek,";J");
   while (ptc) {
   _  pt2 = ptc + 2;
   _  if (strchr("-S",*pt2))
		     /* 「JS2=*...」は２つ前の訳文に "..." が含まれる事を要求*/
   _     ++pt2;
   _  if (isdigit(*pt2) || strchr("AZ",*pt2)) {
   _  _  if ((((++pt2) == strstr(pt2,">>>")) && isdigit(*(pt2 + 3))) || ((pt2 == strstr(pt2,"<<")) && isdigit(*(pt2 + 2))))
   _  _     ptc = pt2 + 3; /* Jn>>>数, Jn<<数  は数値の大小判定条件 */
   _  _  else {
   _  _  _  if (*pt2 == '<')
   _  _  _     ++pt2;
   _  _  _  if ((*pt2 == '=') || (*pt2 == '>')) {
   _  _  _  _  if (isdigit(*(++pt2)) || strchr("X?!|#%()",*pt2) || ((*(ptc + 2) == 'S') && (*pt2 == '*')))
	      /* Jn=(アルファベット)または(,.:?!/-*)または空白のいずれか */
	      /* 「Jn=」は n 番目の（英 !!）訳語をチェックする！！ */
   _  _  _  _     ptc = pt2;
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  _  else {
   _  _  _  _  chk = 0;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  }
   _  else {
   _  _  if ((pt2 == strstr(pt2,"PS=*")) || (pt2 == strstr(pt2,"PS<>")))
   _  _     ptc = pt2;
		     /* 「PJS=*...」は１つ前の訳文に "..." が含まれる事を要求*/
   _  _  else {
   _  _  _  chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  ptc = strstr(ptc,";J");
   }
   if (! chk)
      FormAlert(ptek,ptc,pt2);     /* 適訳条件書式の違反を警告する。*/
end

static void EFormcheck(char ptek[])
		       /* 英単語 en[] に関する適用条件の書式をチェックする。*/
begin
   int  chk = 2;
   char *ptc, *pt2;

   ptc = strstr(ptek,";E");
   while(ptc) {
   _  pt2 = ptc + 2;
   _  if (*pt2 == '-')
   _     ++pt2;
   _  if (isdigit(*pt2) || strchr("AZBG",*pt2)) {
   _  _  if (strchr("<S",*(++pt2)))
   _  _     ++pt2;
   _  _  if (*pt2 == '<')
   _  _     ++pt2;
   _  _  if ((*pt2 == '=') || (*pt2 == '>')) {
   _  _  _  if (isalpha(*(++pt2)) || strchr(",.:?!/* ()-",*pt2))
   _  _  _     ptc = pt2;
   _  _  _  else {
   _  _  _  _  if ((*(ptc + 2) == 'B') && ((*pt2 == '\\') || (*pt2 == '\"')))
   _  _  _  _     ptc = pt2 + 1;
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  }
   _  _  else {
   _  _  _  chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  else {   /*  ptc - 2 = "33;E;1;....." の場合 */
   _  _  if ((*pt2 == ';') && (*(pt2 + 1) == '1') && (*(ptc - 1) == '3') && (*(ptc - 2) == '3'))
   _  _     ptc = pt2 + 2;
   _  _  else {
   _  _  _  chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  ptc = strstr(ptc,";E");
   }
   if (! chk)
      FormAlert(ptek,ptc,pt2);     /* 適訳条件書式の違反を警告する。*/
end


static void FormAlert(char ptek[], char *ptc, char *pt2)
			      /* 適訳条件書式の違反を警告する。*/
begin
   char qptek[160], errPart[WordLen];

   beeping(2);
   color_red;
   printf("\n\n 適訳規則の適用条件に間違いがあります。エディターを使って修正して下さい。\n");
   color_white;
   ptcpy(qptek,ptek,ptc);
   ptcpy(errPart,ptc,pt2 + 2);
   printf(" 適訳規則 = ");
   color_light_blue;
   printf("%s",qptek);
   color_yellow;
   printf("%s",errPart);
   color_light_blue;
   printf("%s",pt2 + 2);
   color_white;
   printf("\n\n 適用条件の書き方　\n");
   printf("    品詞の指定   => ");
   color_yellow;
   printf("J");
   color_green;
   printf("n");
   color_white;
   printf("=品詞コード(数字);\n");
   printf("    属性の指定   => ");
   color_yellow;
   printf("T");
   color_green;
   printf("n");
   color_white;
   printf("=属性コード(アルファベット);\n");
   printf("    英単語の指定 => ");
   color_yellow;
   printf("E");
   color_green;
   printf("n");
   color_white;
   printf("=文字列(アルファベット);\n");
   printf("    日本語辞書見出し語の指定   => ");
   color_yellow;
   printf("DJ");
   color_green;
   printf("n");
   color_white;
   printf("=日本語文字列;\n");
   printf("    原文中の日本語単語の指定   => ");
   color_yellow;
   printf("DI");
   color_green;
   printf("n");
   color_white;
   printf("=日本語文字列;\n");
   printf("    助数詞の指定 => ");
   color_yellow;
   printf("D");
   color_green;
   printf("n");
   color_white;
   printf("=文字(漢字またはひらがな);\n");
   printf("    第２属性の指定 => ");
   color_yellow;
   printf("DD");
   color_green;
   printf("n");
   color_white;
   printf("=文字列(全角と半角が混じってもよい);\n");
   printf("上の書式で ");
   color_green;
   printf("n");
   color_white;
   printf(" は、正、ゼロ、または負の整数か A(前方) または Z(後方) を表します。\n\n");
   exit(1);
   }

void bunFormcheck(void) /* 文法規則の書式をチェックする。*/
begin   /* global variable: pbun[] */
   int  ln, chk;
   char qpbun[185], rem[2][5] = {"先頭","末尾"};
   char *ptc, errPart[WordLen];

   /*    DEBUG   */
/*   printf("\n pbun = %s ",pbun);  */
   /*    DEBUG   */
   while (*pbun == ' ')
      ptcut(pbun,1);
   ln = strlen(pbun);
   while ((*(pbun + ln - 1) == '\n') || (*(pbun + ln - 1) == ' ')) {
   _  *(pbun + ln - 1) = '\0';
   _  --ln;
   }
   if (ln > 182) {
   _  printf("\n 文法規則が長過ぎます。\n");
   _  printf("      pbun = ");
   _  color_light_blue;
   _  printf("%s \n",pbun);
   _  color_white;
   _  printf("\n 長さ = %d  これを 182 文字以内に削ってください。\n",ln);
   _  exit(1);
   }
   chk = 2;
   if (pbun == strstr(pbun,"***")) {
   _  if (strcmp(pbun + ln - 3,"***"))
   _     chk = 1;         /* コメント行は、前後に３つ以上の星(***)が有る。*/
   }
   else {
   _  ptc = strstr(pbun,"  ");
   _  if (ptc && (*(ptc - 1) != '+')) {
   _  _  beeping(2);
   _  _  color_red;
   _  _  printf("\n\n 文法規則に余分な空白があります。エディターを使って削除して下さい。\n");
   _  _  color_white;
   _  _  ptcpy(qpbun,pbun,ptc - 1);
   _  _  ptcpy(errPart,ptc - 1,ptc + 3);
   _  _  printf(" 文法規則 = ");
   _  _  color_light_blue;
   _  _  printf("%s",qpbun);
   _  _  color_yellow;
   _  _  printf("%s",errPart);
   _  _  color_light_blue;
   _  _  printf("%s",ptc + 3);
   _  _  exit(1);
   _  }
   _  if ((! isdigit(*pbun)) || (*(pbun + 1) != ';') || (! strchr("0123456789X|",*(pbun + 2))))
	 /* 文法規則の先頭は「(ステップ番号);(品詞コード列);....」のはず。*/
   _     chk = 0;
   _  else
   _     if ((ln < 7) || (*(pbun + ln - 1) != ';') || (! strchr("0123456789",*(pbun + ln - 2))) || (*(pbun + ln - 6) != ' '))
	       /* 文法規則の末尾は「...;(半角空白)(４桁の番号);」のはず。*/
   _        chk = 1;
   _  if (chk == 2)      /* 文法規則 pbun[] の先頭と末尾の書式のチェック */
   _     chk = bunHdTlCk(ln);
   }
   if (chk < 2) {
   _  beeping(2);
   _  if (ln < 20)
   _     strcpy(qpbun,pbun);
   _  else {
   _  _  ptcpy(qpbun,pbun,pbun + 10);
   _  _  strcat(qpbun,".....");
   _  _  strcat(qpbun,pbun + ln - 7);
   _  }
   _  color_red;
   _  printf("\n\n 文法規則の%sの部分が書式に合致していません。エディターで訂正して下さい！！ \n",rem[chk]);
   _  color_white;
   _  printf(" 文法規則 = ");
   _  color_yellow;
   _  printf("%s \n\n",qpbun);
   _  color_white;
   _  exit(1);
   }
   ptc = strstr(pbun,";;");
   if (ptc) {
   _  beeping(2);
   _  color_red;
   _  printf("\n\n 文法規則に空白欄があります。エディターを使って削除して下さい。\n");
   _  color_white;
   _  ptcpy(qpbun,pbun,ptc);
   _  ptcpy(errPart,ptc,ptc + 2);
   _  printf(" 文法規則 = ");
   _  color_light_blue;
   _  printf("%s",qpbun);
   _  color_yellow;
   _  printf("%s",errPart);
   _  color_light_blue;
   _  printf("%s",ptc + 2);
   _  exit(1);
   }
   bCondFormcheck();        /* 文法条件の書式をチェックする。*/
end

int bunHdTlCk(int ln) /* 文法規則 pbun[] の先頭と末尾の書式チェック */ 
begin  /* global variable: pbun[] */
   int  chk = 2;
   char *pt1;
   
   pt1 = strchr(pbun + 3,';');
   if (((! isdigit(*(++pt1))) && (! strchr("X?",*pt1))) || (*(++pt1) != ';') || (! strchr("01",*(++pt1))) || (*(++pt1) != ';'))
     /* 品詞コード列より後ろの書式は「..;(結合後の品詞コード);(結合の正逆=0,1);...」のはず。*/
      chk = 0;
   if (chk == 2) {
   _  pt1 = pbun + ln - 7;
   _  if ((*pt1++ != ';') || ((! isdigit(*(++pt1))) && ((*pt1 < 'A') || (*pt1 > 'Z'))) || (! isdigit(*(++pt1))) || (! isdigit(*(++pt1))) || (! isdigit(*(++pt1))))   /* 規則末尾の参照番号は "0000" から "Z999" まで可能 */
   _     chk = 1;
   }
   return(chk);
end


void bCondFormcheck(void) /* 文法条件の書式をチェックする。*/
begin   /* global variable: pbun[] */
   int  chk;
   char *ptc, *pt2;

   bJFormcheck(); /* 日本語訳語 cj[] に関する条件の書式チェック */
		  /* 異常が有れば、プログラムを強制終了する。(exit) */
   chk = 2;
   ptc = strstr(pbun,";T");
   while(ptc) {
		       /* 属性変数 cz[] に関する条件の記述チェック */
   _  pt2 = ptc + 2;
   _  if (*pt2 == '-')
   _     ++pt2;
   _  if (isdigit(*pt2) || strchr("AZ#",*pt2)) {
   _  _  if (*(++pt2) == '<')
   _  _     ++pt2;
   _  _  if (strchr("=>#",*pt2)) { /* 等号(=)、不等号(<>)、文法コマンド(#) */
   _  _  _  if (*pt2 == '#') {     /* 文法操作コマンドの場合 */
   _  _  _  _  if (strchr("+-&KZ",*(++pt2))) {
   _  _  _  _  _  chk = 5;   /* Tn#+..., Tn#-..., Tn#&..., Tn#KAZ1, Tn#Z */
   _  _  _  _  _  ptc = pt2;
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  chk = 0; /* 書式違反が有れば chk : 2 => 0 となる。*/
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  _  else { /* （不）等号条件だった場合 */
   _  _  _  _  if (chk == 5) {
		  /* 文法コマンド(#)より後ろに適用条件が書いて有る場合 */
		  /* chk : 2 => 1 と置く。これも違反として警告する。*/
   _  _  _  _  _  chk = 1;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  _  else
   _  _  _  _     ptc = pt2;
   _  _  _  }
   _  _  }
   _  _  else {
   _  _  _  chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  else {
   _  _  chk = 0;
   _  _  break;
   _  }
   _  ptc = strstr(ptc,";T");
   }
   if (chk >= 2)
      bEFormcheck(); /* 英単語 en[] に関する条件の書式チェック */
   if (chk >= 2) {
   _  ptc = strstr(pbun,";D");
   _  while(ptc) { /* 倍角文字列に関する条件書式チェック */
   _  _  pt2 = ptc + 2;
   _  _  if (strchr("DIJ",*pt2))
   _  _     ++pt2;           /* Dn = ".." および DIn/DJn/DDn = "...."  */
   _  _  if (*pt2 == '-')
   _  _     ++pt2;
   _  _  if (isdigit(*pt2) || strchr("AZ",*pt2)) {
   _  _  _  if (*(++pt2) == '<')
   _  _  _     ++pt2;
   _  _  _  if ((*pt2 == '=') || (*pt2 == '>'))
   _  _  _     ptc = pt2;
   _  _  _  else {
   _  _  _  _  if (*pt2 != '#')
   _  _  _  _     chk = 0;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  _  else {  /* ptc = ";DF2J=...." の場合 */
   _  _  _  if ((*pt2 == 'F') && (*(pt2 + 1) == '2') && (*(pt2 + 2) == 'J')) {
   _  _  _  _  pt2 += 3;
   _  _  _  _  if ((*pt2 == '=') || ((*pt2 == '<') && (*(pt2 + 1) == '>')))
   _  _  _  _     ptc = pt2;
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  _  else {
   _  _  _  _  chk = 0;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  _  ptc = strstr(ptc,";D");
   _  }
   }
   if (chk <= 1)
      bFormAlert(ptc,pt2, chk);     /* 文法規則書式の違反を警告する。*/
end

void bJFormcheck(void) /* 日本語訳語に関する条件の書式をチェックする。*/
begin   /* global variable: pbun[] */
   int  chk;
   char *ptc, *pt2;

   chk = 2;
   ptc = strstr(pbun,";J");
   while (ptc) {
   _  pt2 = ptc + 2;
   _  if (strchr("-S",*pt2))
		     /* 「JS2=*...」は２つ前の訳文に "..." が含まれる事を要求*/
   _     ++pt2;
   _  if (isdigit(*pt2) || strchr("AZ",*pt2)) {
   _  _  if ((((++pt2) == strstr(pt2,">>>")) && isdigit(*(pt2 + 3))) || ((pt2 == strstr(pt2,"<<")) && isdigit(*(pt2 + 2))))
   _  _     ptc = pt2 + 3; /* Jn>>>数, Jn<<数  は数値の大小判定条件 */
   _  _  else {
   _  _  _  if (*pt2 == '<')
   _  _  _     ++pt2;
   _  _  _  if ((*pt2 == '=') || (*pt2 == '>')) {
   _  _  _  _  if (isdigit(*(++pt2)) || strchr("X?!|#%",*pt2) || ((*(ptc + 2) == 'S') && (*pt2 == '*'))) {
   _  _  _  _  _  if (chk == 5) {
   _  _  _  _  _  _  chk = 1;
   _  _  _  _  _  _  break;
   _  _  _  _  _  }
   _  _  _  _  _  else
   _  _  _  _  _     ptc = pt2;
	      /* Jn=(アルファベット)または(,.:?!/-*)または空白のいずれか */
	      /* 「Jn=」は n 番目の（英 !!）訳語をチェックする！！ */
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  _  else {
   _  _  _  _  if ((*pt2 == '#')|| ((*pt2 == '-') && (*(pt2 + 1) == '>'))) {
   _  _  _  _  _  chk = 5;     /* 訳語変数 cj[] への文法コマンドの場合 */
   _  _  _  _  _  ptc = pt2;   /* Jn#...; Jn->Jm; Jn<->Jm  */
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  }
   _  }
   _  else {
   _  _  if ((pt2 == strstr(pt2,"PS=")) || (pt2 == strstr(pt2,"PS<>")))
   _  _     ptc = pt2;
		     /* 「PJS=*...」は１つ前の訳文に "..." が含まれる事を要求*/
   _  _  else {
   _  _  _  chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  ptc = strstr(ptc,";J");
   }
   if (chk <= 1)
      bFormAlert(ptc,pt2, chk);     /* 文法規則書式の違反を警告する。*/
end


void bEFormcheck(void) /* 英単語 en[] に関する適用条件の書式をチェックする。*/
begin   /* global variable: pbun[] */
   int  chk = 2;
   char *ptc, *pt2;

   ptc = strstr(pbun,";E");
   while(ptc) {
   _  pt2 = ptc + 2;
   _  if (*pt2 == '-')
   _     ++pt2;
   _  if (isdigit(*pt2) || strchr("AZB",*pt2)) {
   _  _  if (*(++pt2) == '<')
   _  _     ++pt2;
   _  _  if ((*pt2 == '=') || (*pt2 == '>')) {
   _  _  _  if (isalpha(*(++pt2)) || strchr(",.:?!()/-* ()",*pt2) || (*pt2 == '\"') || (*pt2 == '\'') || (pt2 == strstr(pt2,"；")))
	      /* En=(アルファベット)または(,.:?!()/-*)または空白のいずれか */
   _  _  _     ptc = pt2;
   _  _  _  else {
   _  _  _  _  if ((*(ptc + 2) == 'B') && ((*pt2 == '\\') || (*pt2 == '\"')))
    /* EB=\(文字);または EB=\";の場合、１つ前の英文の先頭の文字をチェック */
   _  _  _  _     ptc = pt2 + 1;
   _  _  _  _  else {
   _  _  _  _  _  chk = 0;
   _  _  _  _  _  break;
   _  _  _  _  }
   _  _  _  }
   _  _  }
   _  _  else {
   _  _  _  if (*pt2 != '#')
   _  _  _     chk = 0;
   _  _  _  break;
   _  _  }
   _  }
   _  else
   _     ptc = pt2 + 2;
   _  ptc = strstr(ptc,";E");
   }
   if (! chk)
      bFormAlert(ptc,pt2, chk);     /* 文法規則書式の違反を警告する。*/
end

static void bFormAlert(char *ptc, char *pt2, int chk)
				/* 文法条件書式の違反を警告する。*/
begin   /* global variable: pbun[] */
   char qpbun[190], errPart[WordLen];

   beeping(2);
   if (! chk) {
   _  color_red;
   _  printf("\n\n 文法規則の適用条件に間違いがあります。エディターを使って修正して下さい。\n");
   }
   else {
   _  color_yellow;
   _  printf("\n\n 文法規則の適用条件が文字列処理コマンドより後ろに書かれています。エディターを使って修正して下さい。\n");
   }
   color_white;
   ptcpy(qpbun,pbun,ptc);
   ptcpy(errPart,ptc,pt2 + 2);
   printf(" 文法規則 = ");
   color_light_blue;
   printf("%s",qpbun);
   color_yellow;
   printf(" ***%s***",errPart);
   color_light_blue;
   printf("%s",pt2 + 2);
   color_white;
   printf("\n\n 適用条件の書き方　\n");
   printf("    品詞の指定   => ");
   color_yellow;
   printf("J");
   color_green;
   printf("n");
   color_white;
   printf("=品詞コード(数字);\n");
   printf("    属性の指定   => ");
   color_yellow;
   printf("T");
   color_green;
   printf("n");
   color_white;
   printf("=属性コード(アルファベット);\n");
   printf("    英単語の指定 => ");
   color_yellow;
   printf("E");
   color_green;
   printf("n");
   color_white;
   printf("=文字列(アルファベット);\n");
   printf("    日本語辞書見出し語の指定   => ");
   color_yellow;
   printf("DJ");
   color_green;
   printf("n");
   color_white;
   printf("=日本語文字列;\n");
   printf("    原文中の日本語単語の指定   => ");
   color_yellow;
   printf("DI");
   color_green;
   printf("n");
   color_white;
   printf("=日本語文字列;\n");
   printf("    助数詞の指定 => ");
   color_yellow;
   printf("D");
   color_green;
   printf("n");
   color_white;
   printf("=文字(漢字またはひらがな);\n");
   printf("    第２属性の指定 => ");
   color_yellow;
   printf("DD");
   color_green;
   printf("n");
   color_white;
   printf("=文字列(全角と半角が混じってもよい);\n");
   printf("上の書式で ");
   color_green;
   printf("n");
   color_white;
   printf(" は、正、ゼロ、または負の整数か A(前方) または Z(後方) を表します。\n\n");
   exit(1);
end

