3
3
import Text.Regex.Posix
4
4
import Data.Typeable
5
5
import Data.Data
6
+ import Data.String.Utils as Utils
6
7
7
8
-- Basic Functions
8
9
9
- -- Custom Split Function, for blank space
10
- split :: String -> [String ]
11
- split " " = []
12
- split str = (firstWord str): (split (nextWords str))
10
+ -- Custom split Function, for blank space
11
+ isBlankSpace :: Char -> Bool
12
+ isBlankSpace ch
13
+ | ch == ' ' = True
14
+ | ch == ' \n ' = True
15
+ | ch == ' \t ' = True
16
+ | otherwise = False
17
+
18
+ splitthis :: String -> [String ]
19
+ splitthis " " = []
20
+ splitthis str = (firstWord str): (splitthis (nextWords str))
13
21
14
22
firstWord :: String -> String
15
23
firstWord " " = " "
16
24
firstWord str
17
- | head str == ' ' = " "
25
+ | isBlankSpace $ head str = " "
18
26
| otherwise = (head str): (firstWord (tail str))
19
27
20
28
nextWords :: String -> String
21
29
nextWords " " = " "
22
30
nextWords str
23
- | head str == ' ' = skipAllSpaces (tail str)
31
+ | isBlankSpace $ head str = skipAllSpaces (tail str)
24
32
| otherwise = (nextWords (tail str))
25
33
26
34
skipAllSpaces :: String -> String
27
35
skipAllSpaces " " = " "
28
36
skipAllSpaces str
29
- | ( head str) == ' ' = skipAllSpaces (tail str)
37
+ | isBlankSpace $ head str = skipAllSpaces (tail str)
30
38
| otherwise = str
31
39
32
40
-- Allowed Char
33
41
34
42
data Token =
35
43
Invalid { str :: String }
36
44
| DInt { val :: Integer }
45
+ | DChar { valc :: Char }
46
+ | Dopa { op :: String }
47
+ | Dopb { op :: String }
48
+ | Dopr { op :: String }
49
+ | DReserved { word :: String }
50
+ | DType { datatype :: String }
37
51
| DIdentifier { name :: String }
38
52
deriving (Show ,Eq ,Typeable ,Data )
39
53
data Tokens = Tokens { list :: [Token ]} deriving (Show )
40
- -- newtype Parser tokenType = Parser { parse :: String -> (Bool,[(tokenType,String)]) }
41
54
42
55
sameType x y = (toConstr x) == (toConstr y)
43
56
diffType x y = (toConstr x) /= (toConstr y)
@@ -48,25 +61,51 @@ isValidToken x = diffType x (Invalid "")
48
61
isInvalidToken :: Token -> Bool
49
62
isInvalidToken x = sameType x (Invalid " " )
50
63
51
- -- Parser DInt
64
+ checkReserved :: String -> Token
65
+ checkReserved input
66
+ | input =~ " ^((:=)|(skip)|;|(if)|(then)|(else)|(while))$" :: Bool = DReserved input
67
+ | otherwise = Invalid input
68
+
69
+ checkDataType :: String -> Token
70
+ checkDataType input
71
+ | input =~ " ^((char)|(int))$" :: Bool = DType input
72
+ | otherwise = Invalid input
73
+
52
74
checkInt :: String -> Token
53
75
checkInt input
54
76
| input =~ " ^[0-9]+$" :: Bool = DInt (read input :: Integer )
55
77
| otherwise = Invalid input
56
78
79
+ checkChar :: String -> Token
80
+ checkChar input
81
+ | input =~ " ^'.'$" :: Bool = DChar (input !! 1 )
82
+ | otherwise = Invalid input
83
+
84
+ checkOperator :: String -> Token
85
+ checkOperator input
86
+ | input =~ " ^((\\ +)|(\\ -)|(\\ *)|(\\ /))$" :: Bool = Dopa input
87
+ | input =~ " ^((and)|(or)|(not))$" :: Bool = Dopb input
88
+ | input =~ " ^(([<>]=?)|(==)|(!=))$" :: Bool = Dopr input
89
+ | otherwise = Invalid input
90
+
57
91
checkIdentifier :: String -> Token
58
92
checkIdentifier input
59
93
| input =~ " ^[A-Za-z_][A-Za-z_0-9]*$" :: Bool = DIdentifier input
60
94
| otherwise = Invalid input
61
95
62
96
getToken :: String -> Token
63
97
getToken x
98
+ | isValidToken (checkReserved x) = checkReserved x
99
+ | isValidToken (checkOperator x) = checkOperator x
100
+ | isValidToken (checkDataType x) = checkDataType x
64
101
| isValidToken (checkInt x) = checkInt x
102
+ | isValidToken (checkChar x) = checkChar x
65
103
| isValidToken (checkIdentifier x) = checkIdentifier x
66
104
| otherwise = Invalid x
67
105
106
+
68
107
makeExpression :: String -> Tokens
69
- makeExpression input = Tokens (map getToken (split input))
108
+ makeExpression input = Tokens (map getToken (splitthis input))
70
109
71
110
getTokenList :: Tokens -> [Token ]
72
111
getTokenList (Tokens list) = list
@@ -87,11 +126,45 @@ printTokens tokens = do
87
126
error " Invalid Token Found!!"
88
127
return 0 ;
89
128
129
+ -- In bytes
130
+ getSize :: Token -> Integer
131
+ getSize x
132
+ | x == checkDataType(" int" ) = 4
133
+ | x == checkDataType(" char" ) = 1
134
+ | otherwise = error " Invalid DataType"
135
+
136
+ -- Symbol Table
137
+ data SymbolRow =
138
+ SymbolRow { ident :: Token , itype :: Token , size :: Integer }
139
+
140
+ instance Show SymbolRow where
141
+ show (SymbolRow (DIdentifier ident) (DType itype) size) = " { " ++ ident ++ " , " ++ itype ++ " , " ++ show (size)++ " }\n "
142
+
143
+
144
+ cleanInput :: String -> String
145
+ cleanInput str = Utils. replace " ;" " ; " str
146
+
147
+ -- DataType, rest of Token, out is SymbolTable
148
+ makeSymbolTable :: Token -> [Token ] -> SymbolRow
149
+ makeSymbolTable token tokens
150
+ | (sameType (head tokens) (DIdentifier " x" )) && ((tokens !! 1 ) == checkReserved " ;" ) = SymbolRow (head tokens) (token) (getSize token)
151
+ | otherwise = error " Error! On Variable Declaration"
152
+
153
+ getSymbolTable :: [Token ] -> [SymbolRow ]
154
+ getSymbolTable [] = []
155
+ getSymbolTable tokens
156
+ | sameType (head tokens) (DType " " ) = (makeSymbolTable (head tokens) (tail tokens)) : (getSymbolTable (tail tokens))
157
+ | otherwise = getSymbolTable (tail tokens)
158
+
90
159
main :: IO ()
91
160
main = do
92
- putStr " Enter an expression\n "
93
- a <- getLine
94
- let tokens_collection = (makeExpression a)
161
+ putStr " Enter filename\n "
162
+ filename <- getLine
163
+ a <- readFile filename
164
+ let tokens_collection = (makeExpression $ cleanInput a)
95
165
let invalid_tokens = getInvalidTokens tokens_collection
96
166
printTokens (getTokenList invalid_tokens)
97
- putStr $ (show (tokens_collection) ++ " \n " )
167
+ putStr $ (show (tokens_collection) ++ " \n " )
168
+ putStr $ " \n Symbol Table\n ===========================\n\n "
169
+ putStr $ show $ getSymbolTable $ getTokenList tokens_collection
170
+ putStr $ " \n ===========================\n\n "
0 commit comments