markb@sdcrdcf.UUCP (Mark Biggar) (08/27/83)
\* Just for fun here is a program that does a fairly good job of */ \* translating English text into pig latin. */ #include <stdio.h> #include <ctype.h> #define TRUE 1 #define FALSE 0 main(argc,argv) /* pig -- piglatin filter */ int argc; char *argv[]; { FILE *fp; /* input file pointer */ if (argc == 1) /* no args -- process std input */ latinize(stdin); else while (-argc > 0) /* process each file */ if ((fp = fopen(*++argv,"r")) == NULL) { /* open file */ fprintf(stderr,"pig: can't open %s\n",*argv); exit(1); } else { latinize(fp); /* process new file */ fclose(fp); } exit(0); } isvowel(c) /* function to determine if letter is a vowel */ int c; { if (islower(c)) c = toupper(c); /* cvt to UC */ return ((c=='A') || (c=='E') || (c=='I') || (c=='O') || (c=='U') || (c=='Y')) ;} char s[30] = ""; /* tmp store for consonants */ int sptr = 0; /* pointer to next con save place */ save(c) /* procedure to save consonants */ int c; { s[sptr++] = c; s[sptr] = '\0' /* make string printable */ ;} ccout() /* procedure to print saved consonants */ { printf(s); s[0] = '\0'; /* empty con save string */ sptr = 0 ;} /* STATE TRANSITION TABLE Input Character Last State | Punct | Const | Vowel | Y | - - - - - -+-------------------------------+ LFW | LFW | CC | CRW | FY | - - - - - -+-------------------------------+ CC | LFW | CC | CRW | CC | - - - - - -+-------------------------------+ CRW | LFW | CRW | CRW | CRW | - - - - - -+-------------------------------+ FY | LFW | CRW | CRW | CRW | - - - - - -+-------------------------------+ NOTE: State transition is modified by consonant collection, capilitazation, and the "QU" problem. */ /* Define State Values */ #define LFW 0 /* Looking For Word */ #define CC 1 /* Collecting Consonants */ #define FY 2 /* Found Y */ #define CRW 3 /* Collecting the Rest of Word */ /* Routine to convert to piglatin */ latinize(ffp) FILE *ffp; /* file to be processed */ { int c, /* current input character */ state; /* current state */ int cflg, /* capitalization flag */ qflg, /* last letter q flag */ wcflag; /* word all caps */ state = LFW; /* initial state is looking for word */ while ( (c = getc(ffp)) != EOF ){ switch ( state ){ case LFW: /* looking for word */ cflg = qflg = wcflag = FALSE; /* reset Cap and q flags */ if ( !isalpha(c) ){ putchar(c) /* all punct get dumped here */ ;} else if ( c == 'y' || c == 'Y' ){ /* must treat y's different */ state = FY; if ( isupper(c) ){ cflg = TRUE ;} ;} else if ( isvowel(c) ){ putchar(c); state = CRW ;} else { if ( isupper(c) ){ /* must remember if UC */ cflg = 1; c = tolower(c) ;}; if ( c=='q' ){ qflg = TRUE ;}; /* remember q's */ save(c); state = CC ;}; break;; case FY: if ( !isalpha(c) ){ putchar(cflg ? 'Y' : 'y'); /* alone y */ putchar(c); state = LFW ;} else if ( isvowel(c) ){ /* treat as consonant */ save('y'); putchar((cflg && !isupper(c)) ? toupper(c) : c); state = CRW ;} else { /* treat as vowel */ putchar(cflg ? 'Y' : 'y'); putchar(c); state = CRW ;}; break;; case CC: if ( !isalpha(c) ){ /* no vowels !!!! */ ccout(); putchar(c); state = LFW ;} else if ( isvowel(c) ){ /* start of xlated word */ if ( qflg && c=='u' ){ /* u after q is consonant */ save(c); qflg = FALSE ;} else { putchar((cflg && !isupper(c)) ? toupper(c) : c); if ( isupper(c) ){ wcflag = TRUE; if ( sptr ){ s[0] = toupper(s[0]) ;} ;}; state = CRW ;} ;} else { if ( c=='q' ){ qflg = TRUE ;}; /* remember q'S */ save (c) ;}; break;; case CRW: if ( !isalpha(c) ){ /* word is done */ if ( sptr==0 ){ /* if start was vowel */ if ( wcflag ){ printf("WAY") ;} else { printf("way") ;} ;} else { /* start was consonant */ ccout(); if ( wcflag ){ printf("AY") ;} else { printf("ay") ;} ;}; putchar(c); state = LFW /* go look for next word */ ;} else { putchar(c); /* just pass along vowels */ if ( isupper(c) ){ wcflag = TRUE; if ( sptr ){ s[0] = toupper(s[0]) ;} ;} ;} ;} ;} ;}