56 lines
1.3 KiB
Standard ML
56 lines
1.3 KiB
Standard ML
|
|
signature PARSE_FILE =
|
||
|
|
sig
|
||
|
|
val parseLine: string -> AppType.triangle option
|
||
|
|
end
|
||
|
|
|
||
|
|
structure ParseFile :> PARSE_FILE =
|
||
|
|
struct
|
||
|
|
datatype triangle_token = X | Y | COORD of Real32.real | UNKNOWN of string
|
||
|
|
|
||
|
|
fun extractTriangle lst =
|
||
|
|
case lst of
|
||
|
|
[ X, COORD x1
|
||
|
|
, Y, COORD y1
|
||
|
|
, X, COORD x2
|
||
|
|
|
||
|
|
, Y, COORD y2
|
||
|
|
, X, COORD x3
|
||
|
|
, Y, COORD y3
|
||
|
|
] => SOME {x1 = x1, y1 = y1, x2 = x2, y2 = y2, x3 = x3, y3 = y3}
|
||
|
|
| _ => NONE
|
||
|
|
|
||
|
|
fun tokeniseString str =
|
||
|
|
if str = "x" then
|
||
|
|
X
|
||
|
|
else if str = "y" then
|
||
|
|
Y
|
||
|
|
else
|
||
|
|
case Real32.fromString str of
|
||
|
|
SOME num => COORD num
|
||
|
|
| NONE => UNKNOWN str
|
||
|
|
|
||
|
|
fun helpParseLine (line, pos, acc, lastSpacePos) =
|
||
|
|
if pos = String.size line then
|
||
|
|
List.rev acc
|
||
|
|
else
|
||
|
|
let
|
||
|
|
val chr = String.sub (line, pos)
|
||
|
|
in
|
||
|
|
if chr = #" " orelse chr = #"\n" then
|
||
|
|
let
|
||
|
|
val strToken = String.substring
|
||
|
|
(line, lastSpacePos + 1, pos - (lastSpacePos + 1))
|
||
|
|
val token = tokeniseString strToken
|
||
|
|
in
|
||
|
|
helpParseLine (line, pos + 1, token :: acc, pos)
|
||
|
|
end
|
||
|
|
else
|
||
|
|
helpParseLine (line, pos + 1, acc, lastSpacePos)
|
||
|
|
end
|
||
|
|
|
||
|
|
fun parseLine line =
|
||
|
|
let val lst = helpParseLine (line, 0, [], ~1)
|
||
|
|
in extractTriangle lst
|
||
|
|
end
|
||
|
|
end
|