-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser2.3.rkt
199 lines (157 loc) · 7.85 KB
/
parser2.3.rkt
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#lang racket
(require parser-tools/lex
(prefix-in : parser-tools/lex-sre))
(require data/either)
(require data/monad)
(require data/functor)
(define (either-chain f E)
(if (failure? E)
E
(f (from-success 0 E))))
;variable for counting the line number
(define n 1)
;funcation for making token from input string
(define scanner
(lexer
["while" (cons `(while, n,"while")(scanner input-port))]
["endwhile" (cons `(endwhile, n,"endwhile")(scanner input-port))]
["read" (cons `(read,n,"read")(scanner input-port))]
["write" (cons `(write,n,"write")(scanner input-port))]
["if" (cons `(if,n,"if")(scanner input-port))]
["goto" (cons `(goto,n,"goto")(scanner input-port))]
["gosub" (cons `(gosub,n,"gosub")(scanner input-port))]
["return" (cons `(return,n,"return")(scanner input-port))]
["break" (cons `(break,n,"break")(scanner input-port))]
["end" (cons `(end,n,"end")(scanner input-port))]
["true" (cons `(TRUE,n,"true")(scanner input-port))]
["false" (cons `(FALSE,n,"false")(scanner input-port))]
["=" (cons `(ASSIG,n,"=")(scanner input-port))]
["$$" (cons `(dollar,n)(scanner input-port))]
[(:or "+" "-" "*" "/" "*")(cons `(OP ,n,(string->symbol lexeme))(scanner input-port))]
[(:or "<" ">" ">=" "<>" "<=")(cons `(BOOLOP ,n,(string->symbol lexeme))(scanner input-port))] ;test
[(::(:or (char-range #\a #\z) (char-range #\A #\Z))(:* (:or (char-range #\a #\z) (char-range #\A #\Z)(char-range #\0 #\9)))) (cons `(ID ,n,lexeme)(scanner input-port))]
[(repetition 1 +inf.0
(char-range #\0 #\9))(cons `(Digit ,n,lexeme)(scanner input-port))]
[#\: (cons `(colon,n,"colon")(scanner input-port))]
[#\; (cons `(SEMI,n,"semicolon")(scanner input-port))]
[#\( (cons `(LPAR,n,"left pranthese")(scanner input-port))]
[#\) (cons `(RPAR,n,"right pranthese")(scanner input-port))]
[#\newline (begin (set! n (add1 n))(scanner input-port))]
[whitespace (scanner input-port)]
[(eof) '()]
))
;PARSER FUNCATIONS START FROM HERE.
;funcation for the NUMSIGN production.
;numsign -> + | - | epsilon
(define (num-sign token-list)
(cond [(equal? (third(first token-list)) '(+))(success (rest token-list))]
[(equal? (third(first token-list)) '(-)) (success (rest token-list))]
[else (success token-list)]))
;Fucation for the NUM non-terminal.
;num -> numsign digit digit*
(define (num token-list)
(cond
[(empty? token-list) (failure '(n))]
[(equal? (car(first token-list)) 'Digit) (success (rest token-list))]
[else ((failure (cdr(first token-list))))]
))
;Fucation for the etail non-terminal.
;etail -> + expr | - expr | * expr | / expr | epsilon
(define (etail token-list)
(if (equal? (car(first token-list)) 'OP)(expr (rest token-list))(success token-list)))
;Fucation for the expr non-terminal.
;expr -> id etail | num etail | (expr)
(define (expr token-list)
(cond
[(empty? token-list) (failure '(n))]
[(equal? (car(first token-list)) 'ID) (etail (rest token-list))]
[(equal? (car(first token-list)) 'LPAR)(chain close-prathenses(expr (rest token-list)))]
[ success? (chain etail (chain num (num-sign token-list)))]
[else ((failure (cdr(first token-list))))]))
;bool-op production
;bool-op -> < | > | >= | <= | <> | =
(define (bool-op token-list)
(if(or(equal? (car(first token-list)) 'BOOLOP)(equal? (car(first token-list)) 'ASSIG))(success (rest token-list))((failure (cdr(first token-list))))))
;boolean production
;boolean -> true | false | expr bool-op expr
(define (boolean token-list)
(cond[(or (equal? (car(first token-list)) 'TRUE)(equal? (car(first token-list)) 'FALSE)) (success (rest token-list))]
[else (chain expr (chain bool-op(expr token-list)))]
))
;return success if semicolon found else failure
(define (semicolon token-list)
(if (equal? (car(first token-list)) 'SEMI) (success ( rest token-list))(failure (cdr(first token-list)))))
(define (open-prathenses token-list)
(if (equal? (car(first token-list)) 'LPAR)(success (rest token-list))(failure (cdr(first token-list)))))
(define (close-prathenses token-list)
(if (equal? (car(first token-list)) 'RPAR)(success (rest token-list))(failure (cdr(first token-list)))))
(define (id token-list)
(if (equal? (car(first token-list)) 'ID) (success (rest token-list))(failure (cdr(first token-list)))))
(define (endwhile token-list)
(cond[(equal? (car(first token-list)) 'endwhile) (success (rest token-list))]
[else (failure (cdr(first token-list)))] ;change
))
;stmt production
(define (stmt token-list)
(cond
[(< (length token-list) 2) (failure '(n))] ;if list size less than 2 than we don't have enough entities to have a syntatically correct code
[(and (equal? (car(first token-list)) 'ID) (equal? (car(second token-list)) 'ASSIG) )(chain semicolon (expr (rest ( rest token-list))))]
[(equal? (car(first token-list)) 'if) (chain semicolon( chain stmt(chain close-prathenses(chain boolean(open-prathenses(rest token-list))))))]
[(equal? (car(first token-list)) 'read) (chain semicolon(id (rest token-list)))]
[(equal? (car(first token-list)) 'write)(chain semicolon(expr (rest token-list)))]
[(equal? (car(first token-list)) 'goto)(chain semicolon(id (rest token-list)))]
[(equal? (car(first token-list)) 'gosub)(chain semicolon(id (rest token-list)))]
[(equal? (car(first token-list)) 'return) (semicolon (rest token-list))]
[(equal? (car(first token-list)) 'break) (semicolon (rest token-list))]
[(equal? (car(first token-list)) 'end) (semicolon (rest token-list))]
[(equal? (car(first token-list)) 'while) (chain semicolon (chain endwhile (chain linelist(chain close-prathenses(chain boolean(open-prathenses (rest token-list)))))))]
[else (failure (cdr(first token-list)))]
))
;linetail production
;linetail -> stmt+ | epsilon
(define (linetail token-list)
(cond
[(empty? token-list)(success token-list)]
;[(equal? (car(first token-list)) 'dollar) (begin(displayln 1)(success token-list))]
[(success? (stmt token-list))(chain linetail(stmt token-list))]
[else (success token-list)])
)
(define (colon token-list)
(if(equal? (car (first token-list)) 'colon)(success (rest token-list))(success token-list)))
;label production
;label -> id: | epsilon
(define (label token-list)
(cond
[(empty? token-list) (failure '(n))]
[(and (equal? (car(first token-list)) 'ID) (equal? (car(second token-list)) 'colon))(success ( rest( rest token-list)))]
[else (success token-list)]
))
;line production
;line -> label stmt linetail
(define (line token-list)
;(displayln (car(first token-list)))
(chain linetail(chain stmt(label token-list))))
;linelist production
;linelist -> line linelist | epsilon
(define (linelist token-list)
(cond
[(empty? token-list)(failure '(n))]
[(equal? (car(first token-list)) 'dollar) (success token-list)]
[ (success? (chain linelist (line token-list)))(chain linelist (line token-list))] ;[success? (chain linelist (line token-list))]
[else (success token-list)]
))
;check if we have $$ sign at the end of the program
(define (dollar token-list)
(if (equal? (car(first token-list)) 'dollar) (success ( rest token-list))(failure (cdr(first token-list)))))
(define (program token-list)
(let([result (chain dollar(linelist token-list))])
(cond
[(success? result)(displayln "Accepted!!")]
[else (displayln (~a "Syntax Error at line " (car(from-failure '() (result)))))]
))
)
(define (parse s)
(cond [(string? s)(let([file-contents (open-input-file s)]) (parse (scanner file-contents)))]
[else (begin (set! n 1)(program s))]
)
)