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;
Aihe on jo aika vanha, joten et voi enää vastata siihen.