enhanced_status.anubis 11.1 KB
/*
 * 
 * User: David RENE
 * Date: 30/05/2008
 * Time: 03:30
 * (c) Calexium
 *
 */


   
   
read tools/basis.anubis   

   
   We  want   to  test  email   addresses.  Below  is   a  regular  expression   for  that
   purpose. Actually, this expression is too nave. A real one would be more complicated. 
   

read tools/streams.anubis   
read system/string.anubis
   
type LM_TokenOrError_EnhancedStatus:
  end_of_file, 
  token(List(Word8)),
  error. 

type LM_LexerState_EnhancedStatus: ...

type LM_Match_EnhancedStatus:
  match(List(Word8) characters, 
        (LM_LexerState_EnhancedStatus,List(Word8)) -> (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) action,
        Bool aeol,
        Bool abol). 

type LM_LexerState_EnhancedStatus:
  lexer_state(Stream                 input,
              List(Word8)             unput,         // in natural order
              List(Word8)             more,          // in reverse order
              LM_LexerState_EnhancedStatus -> (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) lexer, 
              Bool                   at_end_of_line,
              Bool                   at_beginning_of_line,
              Maybe(LM_Match_EnhancedStatus)        match). 

define LM_LexerState_EnhancedStatus
  lm_initial_state
    (
      Stream input,
      LM_LexerState_EnhancedStatus -> (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) lexer
    ) =
  lexer_state(input,[],[],lexer,false,true,failure). 

define (LM_LexerState_EnhancedStatus,Word8)
  lm_next_char
    (
      LM_LexerState_EnhancedStatus ls
    ) =
  if ls is lexer_state(input,unput,more,lex,aeol,abol,match) then 
  if unput is
    {
      [ ] then
        if read_byte(input) is 
          {
            failure then
              (lexer_state(input,
                           [],
                           more,
                           lex,
                           true,
                           aeol,
                           match),
               -1),

            success(c) then 
              (lexer_state(input,
                           [],
                           [c . more],
                           lex,
                           c = '\n',
                           aeol,
                           match),
               c),
          },
               
      [h . t] then 
        (lexer_state(input,
                     t,
                     [h . more],
                     lex,
                     h = '\n',
                     aeol,
                     match),
         h)
    }. 

define LM_LexerState_EnhancedStatus
  lm_remember_match
    (
      (LM_LexerState_EnhancedStatus,List(Word8)) -> (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) action,
      LM_LexerState_EnhancedStatus ls
    ) =
  if ls is lexer_state(input,unput,more,lex,aeol,abol,m) then 
  with chars = if m is 
    {
      failure then [], 
      success(match) then 
        if match is match(chars,_,_,_) then chars
    },
  lexer_state(input,
              unput,
              [],
              lex,
              aeol,
              abol,
              success(match(append(more,chars),action,aeol,abol))).

define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  lm_find_match
    (
      LM_LexerState_EnhancedStatus ls
    ) =
  if ls is lexer_state(input,unput,more,lex,_,_,mb_m) then 
  if mb_m is 
    {
      failure then (ls,error), 
      success(m) then
        if m is match(chars,action,aeol,abol) then 
           action(lexer_state(input,
                              append(more,unput),
                              [],
                              lex,
                              aeol,
                              abol,
                              failure),
                  reverse(chars))
    }.

define LM_LexerState_EnhancedStatus
  change_lexer
    (
      LM_LexerState_EnhancedStatus ls, 
      LM_LexerState_EnhancedStatus -> (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) lex
    ) =
  if ls is lexer_state(input,unput,more,_,aeol,abol,mb_m) then 
  lexer_state(input,unput,more,lex,aeol,abol,mb_m). 

define LM_LexerState_EnhancedStatus
  clear_abol
    (
      LM_LexerState_EnhancedStatus ls
    ) =
  if ls is lexer_state(input,unput,more,lex,aeol,_,mb_m) then 
  lexer_state(input,unput,more,lex,aeol,false,mb_m). 

   Declarations of all lexer states.


public define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_1(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_2(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_3(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_4(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_5(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_6(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_7(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_state_8(LM_LexerState_EnhancedStatus ls).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_action_0
   (LM_LexerState_EnhancedStatus ls, List(Word8) text).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_action_1
   (LM_LexerState_EnhancedStatus ls, List(Word8) text).
define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus) enhanced_status_tester_action_2
   (LM_LexerState_EnhancedStatus ls, List(Word8) text).


   Lexer states.


public define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  if at_beginning_of_line(ls)
  then enhanced_status_tester_state_3(clear_abol(ls)) else
  if lm_next_char(ls) is (ls,c) then
  if c = -1 then enhanced_status_tester_state_1(ls) else
  if c = 50 then enhanced_status_tester_state_4(ls) else
  if (52 +=< c & c +=< 53) then enhanced_status_tester_state_4(ls) else
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_1
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  with ls = lm_remember_match(enhanced_status_tester_action_2,ls),
  if lm_next_char(ls) is (ls,c) then
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_2
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  if lm_next_char(ls) is (ls,c) then
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_3
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  with ls = lm_remember_match(enhanced_status_tester_action_1,ls),
  if lm_next_char(ls) is (ls,c) then
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_4
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  if lm_next_char(ls) is (ls,c) then
  if c = 46 then enhanced_status_tester_state_5(ls) else
  if c = 50 then enhanced_status_tester_state_4(ls) else
  if (52 +=< c & c +=< 53) then enhanced_status_tester_state_4(ls) else
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_5
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  if lm_next_char(ls) is (ls,c) then
  if c = 46 then enhanced_status_tester_state_5(ls) else
  if (48 +=< c & c +=< 57) then enhanced_status_tester_state_6(ls) else
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_6
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  if lm_next_char(ls) is (ls,c) then
  if c = 46 then enhanced_status_tester_state_7(ls) else
  if (48 +=< c & c +=< 57) then enhanced_status_tester_state_6(ls) else
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_7
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  if lm_next_char(ls) is (ls,c) then
  if c = 46 then enhanced_status_tester_state_7(ls) else
  if (48 +=< c & c +=< 57) then enhanced_status_tester_state_8(ls) else
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_state_8
    (
      LM_LexerState_EnhancedStatus ls,
    ) =
  with ls = lm_remember_match(enhanced_status_tester_action_0,ls),
  if lm_next_char(ls) is (ls,c) then
  if (48 +=< c & c +=< 57) then enhanced_status_tester_state_8(ls) else
  lm_find_match(ls).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_action_0
    (
      LM_LexerState_EnhancedStatus ls,
      List(Word8) text
    ) =
  (ls,token(text)).


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_action_1
    (
      LM_LexerState_EnhancedStatus ls,
      List(Word8) text
    ) =
   /* default action */ enhanced_status_tester(ls) .


define (LM_LexerState_EnhancedStatus,LM_TokenOrError_EnhancedStatus)
  enhanced_status_tester_action_2
    (
      LM_LexerState_EnhancedStatus ls,
      List(Word8) text
    ) =
   /* default action */ (ls,end_of_file) .


   Since '@' is  a normal character, a string  needs to contain exactly one  '@' for being
   accepted. What is accepted before and after this '@' is described by:
   
          [a-zA-Z]+(\.[a-zA-Z]+)*
   
   The first part: [a-zA-Z]+ means ``at  least one letter''. The last part: (\.[a-zA-Z]+)*
   means: ``a dot followed by at least one  letter, and this may be repeated any number of
   times (including zero)''.
   
   
   This part of the source file is the 'postambule' (just Anubis text, which is copied 'as
   is' to the lexer_maker output file).
   
   The above  stuff produces a function  named 'email_tester' into  the lexer_maker output
   file. This function is used below:
   
define Maybe(String)
  _extract_enhanced_status
  (
    List(String) lines
  ) =
  if lines is 
  {
    [ ]     then failure, 
    [h . t] then 
      with ls = lexer_state(make_stream(h),[],[],enhanced_status_tester,true,false,failure), 
      if enhanced_status_tester(ls) is (_,result) then 
        if result is
        {
          end_of_file  then _extract_enhanced_status(t),
          token(tok)   then success(implode(tok))
          error        then _extract_enhanced_status(t) 
        }
  }.
   
public define Maybe(String)
  extract_enhanced_status
  (
    List(String) lines
  ) =
  if lines is 
  {
    [ ]     then failure, 
    [h . t] then 
      if _extract_enhanced_status(split_by_token(h, ' ')) is
      {
        failure     then extract_enhanced_status(t),
        success(r)  then success(r)
      }
  }.