-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtokenizer.elm
91 lines (86 loc) · 3.12 KB
/
tokenizer.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
module Tokenizer exposing (tokenize)
import Regex exposing (regex)
import Char
import Types exposing (..)
tokenize : String -> Result String (List Token)
tokenize inputString =
let
innerHelper tokensSoFar inputString =
if String.isEmpty inputString
then Ok (List.reverse tokensSoFar)
else
let
tokenizeOneResult = tokenizeOne inputString
in
case tokenizeOneResult of
Err errorString ->
Err errorString
Ok (Nothing, _) ->
Ok (List.reverse tokensSoFar)
Ok (Just token, restOfInputString) ->
innerHelper (token :: tokensSoFar) restOfInputString
in
innerHelper [] inputString
tokenizeOne : String -> (Result String (Maybe Token, String))
tokenizeOne inputString =
let
firstCharMaybe = String.uncons inputString
in
case firstCharMaybe of
Nothing ->
Ok (Nothing, "")
Just (firstChar, restOfInput) ->
case firstChar of
'(' -> Ok (Just (Parenthesis LeftParToken), restOfInput)
')' -> Ok (Just (Parenthesis RightParToken), restOfInput)
'-' -> Ok (Just (NotToken), restOfInput)
'&' -> Ok (Just (BinaryOperator AndToken), restOfInput)
'a' -> Ok (Just (BinaryOperator AndToken), restOfInput)
'|' -> Ok (Just (BinaryOperator OrToken), restOfInput)
'v' -> Ok (Just (BinaryOperator OrToken), restOfInput)
'>' -> Ok (Just (BinaryOperator ImplicationToken), restOfInput)
' ' -> tokenizeOne (String.dropLeft 1 inputString)
_ ->
if
firstChar |> toString |> Regex.contains (regex "[A-Z]")
then
let
propvarToken = tokenizePropvar inputString
in
case propvarToken of
Ok (token, restOfInput) ->
Ok ((Just token), restOfInput)
Err errorMessage ->
Err errorMessage
else if
Char.isLower firstChar
then
Err ("Skjønner ikke dette tegnet: " ++ (toString firstChar) ++ ". Utsagnsvariabler må begynne med stor forbokstav!")
else
Err ("Skjønner ikke dette tegnet: " ++ (toString firstChar))
tokenizePropvar : String -> (Result String (Token, String))
tokenizePropvar inputString =
let
innerHelper readSoFar curInput =
let
curCharMaybe = String.uncons curInput
in
case curCharMaybe of
Nothing ->
Ok (PropvarToken readSoFar, "")
Just (firstChar, restOfInput) ->
let
firstCharStr = toString firstChar
in
if (Regex.contains (regex "[A-Za-z]") firstCharStr) &&
(not (Regex.contains (regex "[av]") firstCharStr))
then
innerHelper ( readSoFar ++ (String.fromChar firstChar)) restOfInput
else
Ok (PropvarToken readSoFar, (String.cons firstChar restOfInput))
in
if String.isEmpty inputString
then
Err "tokenizePropvar: emptyInput"
else
innerHelper "" inputString