Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: PL/I: Tekstikentän validointi

jalski [11.09.2013 10:59:31]

#

Nettiä selatessani törmäsin artikkeliin Windows:in Edit kontrollin validoinnista. Ajattelin linkittää sen tänne koska luulen, että sillä voisi olla käyttöä jollekin.

Löytyypi täältä.

Idea on äärimmäisen simppeli ja käyttää tilakonetta (FSM).

Alla esimerkki kirjoitettuna ohjelmointikielten kuninkaalla PL/I:llä, käyttäen artikkelin mukaista tilakonetta konsoliin syötetyn reaaliluvun validointiin:

*PROCESS MARGINS(1,140) LIBS(SINGLE,STATIC);

test: procedure options(main);
   dcl buffer char(255) varying;
   dcl bad_ch condition;

   /***************************************/
   /* On unit to handle bad characters.   */
   /***************************************/
   on condition(bad_ch)
     begin;
       display('bad characters in input. Allowed characters are '' 0123456789+-.eE''.');
       goto recover;
     end;

  recover:
     display('Input real?') reply(buffer);
     if verify(buffer,' 0123456789+-.eE') then
       signal condition(bad_ch);

   display(validate_real(buffer));


   /*********************************************/
   /* Validates character array for real number */
   /* Returns:                                  */
   /*   0: EMPTY                                */
   /*   1: PARTIAL                              */
   /*   2: OK                                   */
   /*   3: ERROR                                */
   /*********************************************/
   validate_real: procedure(string) returns(fixed bin(31));
     dcl string char(*) varying;

     dcl (i, state, status) fixed bin(16) unsigned;
     dcl ch char(1);

     dcl space_ch char(1) value('20'x);
     dcl tab_ch char(1) value('09'x);

     define ordinal STATUS(EMPTY, PARTIAL, OK, ERROR);
     define ordinal STATE(S0, IPART, FPART, ESIGN, EPART);

     i = 1;
     state = binvalue(S0);
     status = binvalue(EMPTY);

     do while(status ^= binvalue(ERROR) & i <= length(string));
       ch = substr(string,i,1);
       select(makelong(state,asc(ch)));
         when(makelong(binvalue(S0),asc(space_ch)), makelong(binvalue(S0),asc(tab_ch)))
           i+=1;
         when(makelong(binvalue(S0),asc('+')), makelong(binvalue(S0),asc('-')))
           do;
             i+=1;
             state = binvalue(IPART);
             status = binvalue(PARTIAL);
           end;
         when(makelong(binvalue(S0),asc('0')), makelong(binvalue(S0),asc('1')), makelong(binvalue(S0),asc('2')),
              makelong(binvalue(S0),asc('3')), makelong(binvalue(S0),asc('4')), makelong(binvalue(S0),asc('5')),
              makelong(binvalue(S0),asc('6')), makelong(binvalue(S0),asc('7')), makelong(binvalue(S0),asc('8')),
              makelong(binvalue(S0),asc('9')))
           state = binvalue(IPART);
         when(makelong(binvalue(S0),asc('.')))
           do;
             i+=1;
             state = binvalue(FPART);
             status = binvalue(PARTIAL);
           end;
         when(makelong(binvalue(S0),asc('e')), makelong(binvalue(S0),asc('E')))
           do;
             i+=1;
             state = binvalue(ESIGN);
             status = binvalue(PARTIAL);
           end;
         when(makelong(binvalue(IPART),asc('0')), makelong(binvalue(IPART),asc('1')), makelong(binvalue(IPART),asc('2')),
              makelong(binvalue(IPART),asc('3')), makelong(binvalue(IPART),asc('4')), makelong(binvalue(IPART),asc('5')),
              makelong(binvalue(IPART),asc('6')), makelong(binvalue(IPART),asc('7')), makelong(binvalue(IPART),asc('8')),
              makelong(binvalue(IPART),asc('9')))
           do;
             i+=1;
             status = binvalue(OK);
           end;
         when(makelong(binvalue(IPART),asc('.')))
           do;
             i+=1;
             state = binvalue(FPART);
             status = binvalue(OK);
           end;
         when(makelong(binvalue(IPART),asc('e')), makelong(binvalue(IPART),asc('E')))
           do;
             i+=1;
             state = binvalue(ESIGN);
             status = binvalue(PARTIAL);
           end;
         when(makelong(binvalue(FPART),asc('0')), makelong(binvalue(FPART),asc('1')), makelong(binvalue(FPART),asc('2')),
              makelong(binvalue(FPART),asc('3')), makelong(binvalue(FPART),asc('4')), makelong(binvalue(FPART),asc('5')),
              makelong(binvalue(FPART),asc('6')), makelong(binvalue(FPART),asc('7')), makelong(binvalue(FPART),asc('8')),
              makelong(binvalue(FPART),asc('9')))
           do;
             i+=1;
             status = binvalue(OK);
           end;
         when(makelong(binvalue(FPART),asc('e')), makelong(binvalue(FPART),asc('E')))
           do;
             i+=1;
             state = binvalue(ESIGN);
             status = binvalue(PARTIAL);
           end;
         when(makelong(binvalue(ESIGN),asc('+')), makelong(binvalue(ESIGN),asc('-')))
           do;
             i+=1;
             state = binvalue(EPART);
             status = binvalue(PARTIAL);
           end;
         when(makelong(binvalue(ESIGN),asc('0')), makelong(binvalue(ESIGN),asc('1')), makelong(binvalue(ESIGN),asc('2')),
              makelong(binvalue(ESIGN),asc('3')), makelong(binvalue(ESIGN),asc('4')), makelong(binvalue(ESIGN),asc('5')),
              makelong(binvalue(ESIGN),asc('6')), makelong(binvalue(ESIGN),asc('7')), makelong(binvalue(ESIGN),asc('8')),
              makelong(binvalue(ESIGN),asc('9')))
           state = binvalue(EPART);
         when(makelong(binvalue(EPART),asc('0')), makelong(binvalue(EPART),asc('1')), makelong(binvalue(EPART),asc('2')),
              makelong(binvalue(EPART),asc('3')), makelong(binvalue(EPART),asc('4')), makelong(binvalue(EPART),asc('5')),
              makelong(binvalue(EPART),asc('6')), makelong(binvalue(EPART),asc('7')), makelong(binvalue(EPART),asc('8')),
              makelong(binvalue(EPART),asc('9')))
           do;
             i+=1;
             status = binvalue(OK);
           end;
         otherwise
           status = binvalue(ERROR);
       end;
     end;

     return(status);
   end validate_real;


   /************************************/
   /* Return ascii code of a character */
   /************************************/
   asc: procedure(c) returns(fixed bin(8) unsigned);
     dcl c char(1);

     dcl 1 char_byte union,
         2 ch char(1),
         2 byte fixed bin(8) unsigned;

     ch = c;
     return(byte);
   end asc;


   /**************************************************************/
   /* Creates a LONG value by concatenating the specified values */
   /**************************************************************/
   makelong: procedure(wLow,wHigh) returns(fixed bin(32) unsigned);
     dcl (wLow, wHigh) fixed bin(16) unsigned;

     dcl 1 long union,
         2 dword fixed bin(32) unsigned,
         2 word(2) fixed bin(16) unsigned;

     word(1) = wLow;
     word(2) = wHigh;

     return(dword);
   end makelong;


end test;

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta