(* utils *)
(* fold na stringach *)
let foldl f x str =
let len = ( String.length str ) - 1 in
let temp = x in
let result = ref temp in
for i = 0 to len do
result := f !result str.[i];
done;
!result;;
let contains str c = foldl ( fun a b -> a || ( b = c ) ) false str;;
let not_contains str c = not ( contains str c );;
let is_numc c = c >= '0' && c <= '9';;
let is_alfanumc c =
( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ||
( c >= '0' && c <= '9' ) || ( c = '_' );;
let is_whitespacec c = ( c = ' ' || c = '\n' || c = '\t' );;
let is_nums str = foldl ( fun a b -> a && ( is_numc b ) ) true str;;
let is_alfanums str = foldl ( fun a b -> a && ( is_alfanumc b ) ) true str;;
let char_to_int c = match c with
| '0' -> 0
| '1' -> 1
| '2' -> 2
| '3' -> 3
| '4' -> 4
| '5' -> 5
| '6' -> 6
| '7' -> 7
| '8' -> 8
| '9' -> 9
| _ -> failwith "Niepoprawne wejscie";;
let str_to_int str =
let len = ( String.length str ) - 1 in
let result = ref 0 in
for i = 0 to len do
result := !result * 10;
result := !result + ( char_to_int str.[i] );
done;
!result;;
(* parser *)
type token =
| TK_LPAREN (* lewy nawias *)
| TK_RPAREN (* prawy nawias *)
| TK_IF (* IF *)
| TK_DECISION (* DECISION *)
| TK_CASE (* CASE *)
| TK_ELSEIF (* ELSEIF *)
| TK_ARM (* ARM *)
| TK_EQUALS (* EQUALS *)
| TK_AND (* AND *)
| TK_OR (* OR *)
| TK_VAR (* VAR *)
| TK_WILDCARD (* underscore *)
| TK_NUM of int (* ciag numeryczny *)
| TK_ALFANUM of string (* ciag alfanumeryczny *);;
let makeToken str = match str with
| "(" -> TK_LPAREN
| ")" -> TK_RPAREN
| "IF" -> TK_IF
| "DECISION" -> TK_DECISION
| "CASE" -> TK_CASE
| "ELSEIF" -> TK_ELSEIF
| "ARM" -> TK_ARM
| "EQUALS" -> TK_EQUALS
| "AND" -> TK_AND
| "OR" -> TK_OR
| "VAR" -> TK_VAR
| "_" -> TK_WILDCARD
| _ ->
if is_nums str then
TK_NUM( str_to_int str )
else
TK_ALFANUM( str );;
let tokenize str =
let result = ref [] in
let len = String.length str in
let i = ref 0 in
let j = ref 0 in
while !i < len do
if str.[!i] = '(' || str.[!i] = ')' then
(
result := ( makeToken ( String.sub str !i 1 ) )::( !result );
i := !i + 1
)
else if ( is_whitespacec str.[!i] ) then
i := !i + 1
else if is_alfanumc str.[!i] then
(
j := !i;
while !j < len && ( is_alfanumc str.[!j] ) do
j := !j + 1;
done;
result := ( makeToken ( String.sub str !i ( !j - !i ) ) )::( !result );
i := !j
)
else
result := !result
done;
List.rev !result;;