Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jan 4th, 2012  |  syntax: OCaml  |  size: 2.58 KB  |  hits: 82  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. (* utils *)
  2.  
  3. (* fold na stringach *)
  4. let foldl f x str =
  5.         let len = ( String.length str ) - 1 in
  6.         let temp = x in
  7.         let result = ref temp in
  8.         for i = 0 to len do
  9.                 result := f !result str.[i];
  10.         done;
  11.         !result;;
  12.  
  13. let contains str c = foldl ( fun a b -> a || ( b = c ) ) false str;;
  14.  
  15. let not_contains str c = not ( contains str c );;
  16.  
  17. let is_numc c = c >= '0' && c <= '9';;
  18. let is_alfanumc c =
  19.         ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ||
  20.         ( c >= '0' && c <= '9' ) || ( c = '_' );;
  21. let is_whitespacec c = ( c = ' ' || c = '\n' ||  c = '\t' );;
  22.  
  23. let is_nums str = foldl ( fun a b -> a && ( is_numc b ) ) true str;;
  24. let is_alfanums str = foldl ( fun a b -> a && ( is_alfanumc b ) ) true str;;
  25.  
  26. let char_to_int c = match c with
  27.         | '0' -> 0
  28.         | '1' -> 1
  29.         | '2' -> 2
  30.         | '3' -> 3
  31.         | '4' -> 4
  32.         | '5' -> 5
  33.         | '6' -> 6
  34.         | '7' -> 7
  35.         | '8' -> 8
  36.         | '9' -> 9
  37.         | _ -> failwith "Niepoprawne wejscie";;
  38.  
  39. let str_to_int str =
  40.         let len = ( String.length str ) - 1 in
  41.         let result = ref 0 in
  42.         for i = 0 to len do
  43.                 result := !result * 10;
  44.                 result := !result + ( char_to_int str.[i] );
  45.         done;
  46.         !result;;
  47.  
  48. (* parser *)
  49.  
  50. type token =
  51.         | TK_LPAREN                             (* lewy nawias *)
  52.         | TK_RPAREN                             (* prawy nawias *)
  53.         | TK_IF                                 (* IF *)
  54.         | TK_DECISION                   (* DECISION *)
  55.         | TK_CASE                               (* CASE *)
  56.         | TK_ELSEIF                             (* ELSEIF *)
  57.         | TK_ARM                                (* ARM *)
  58.         | TK_EQUALS                             (* EQUALS *)
  59.         | TK_AND                                (* AND *)
  60.         | TK_OR                                 (* OR *)
  61.         | TK_VAR                                (* VAR *)
  62.         | TK_WILDCARD                   (* underscore *)
  63.         | TK_NUM of int                 (* ciag numeryczny *)
  64.         | TK_ALFANUM of string  (* ciag alfanumeryczny *);;
  65.  
  66. let makeToken str = match str with
  67.         | "("                   -> TK_LPAREN
  68.         | ")"                   -> TK_RPAREN
  69.         | "IF"                  -> TK_IF
  70.         | "DECISION"    -> TK_DECISION
  71.         | "CASE"                -> TK_CASE
  72.         | "ELSEIF"              -> TK_ELSEIF
  73.         | "ARM"                 -> TK_ARM
  74.         | "EQUALS"              -> TK_EQUALS
  75.         | "AND"                 -> TK_AND
  76.         | "OR"                  -> TK_OR
  77.         | "VAR"                 -> TK_VAR
  78.         | "_"                   -> TK_WILDCARD
  79.         | _                             ->
  80.                 if is_nums str then
  81.                         TK_NUM( str_to_int str )
  82.                 else
  83.                         TK_ALFANUM( str );;
  84.  
  85. let tokenize str =
  86.         let result = ref [] in
  87.         let len = String.length str in
  88.         let i = ref 0 in
  89.         let j = ref 0 in
  90.         while !i < len do
  91.                 if str.[!i] = '(' || str.[!i] = ')' then
  92.                 (
  93.                         result := ( makeToken ( String.sub str !i 1 ) )::( !result );
  94.                         i := !i + 1
  95.                 )
  96.                 else if ( is_whitespacec str.[!i] ) then
  97.                         i := !i + 1
  98.                 else if is_alfanumc str.[!i] then
  99.                 (
  100.                         j := !i;
  101.                         while !j < len && ( is_alfanumc str.[!j] ) do
  102.                                 j := !j + 1;
  103.                         done;
  104.                         result := ( makeToken ( String.sub str !i ( !j - !i ) ) )::( !result );
  105.                         i := !j
  106.                 )
  107.                 else
  108.                         result := !result
  109.         done;
  110.         List.rev !result;;