Prelude Code: exception Notimplemented exception ParserFailure (** MiniCAML Language Definition") (*Types in MiniCAML *) type typ= Int |Bool (int) (bool) | Pair of typ*typ (*11*12*) | Arrow of typ "typ (* 11 -> 12*) (*We extend types with type variables to support type inference. ༄། Note that this does not have any surface syntax, and is used only for internal processing. | TVar of typ option ref (*Used for identifiers of variables *) type ident string (*The binary operations available in MiniCAML *) type bop= Equals (e1=2") | Less Than ("e1e or rec f>e") Let of ident* exp exp (*let x e1 in e2 end") (*x*) | Var of ident ("Charater Stream") module CStream: sig type t val of string: string->t val is donet-> bool val unconst-> (char *t) option val take: int ->t-> (string *t) option val take while (char -> bool) ->t> string t end = struct type t={input: string; len: int; index: int} let of strings = {input = s; len = String.length s; index = 0} let is done cscs.len = cs.index let uncons cs= if is done cs then None else Some (cs.input.[cs.index], {cs with index = cs.index + 1}) MiniCAML") let take | cs= ("The unary operations available type uop= | Negate (e) (*Expressions in MiniCAML") type exp= Constl of int PrimBop of exp*bop* exp | PrimUop of uop exp | Constẞ of bool If of exp*exp* exp (-2-101|2|...") ("e1 02*) (* e*) (* true | false *) (if e then e1 else e2") ("e1, e2*) | LetComma of ident ident exp exp (let (x, y) = e1 in e2 end") Comma of exp* exp let index = cs.index + 1 in if index <=cs.len then Some (String.sub cs.input cs.index I, {cs with index }) else None let take while pcs = let rec find_index i = in ifi>=cs.len || not (p cs.input.[i]) then i else find index (i + 1) let index = find_index cs.index in (String.sub cs.input cs.index (index - cs.index), {cs with index }) end (*Parser Primitives/Utilities *) module Parser sig type input type 'a output type 'at = input -> 'a output exception InvalidKeyword val run: 'at -> string -> 'a option val of value: 'a-> 'at (read this as "and then" ") val()'at-> ('a -> 'b t) -> 'bt (read this as "before" ) val (>>)'at-> 'bt-> 'bt val fail: 'a t val map: ('a-> 'b) -> 'at -> 'bt val map2: ('a -> 'b-> 'c) -> 'at-> 'bt-> 'ct val map3: ('a -> 'b-> 'c-> 'd) ->'at-> 'bt->'ct->'dt val const_map: 'b-> 'at-> 'bt val first_of_2: 'at-> 'at-> 'at val first of: 'at list -> 'at val many 'at-> 'a list t val some: 'at -> 'a list t val sep_by:'at-> 'bt-> 'a list t val sep_by_1: "at-> 'bt-> 'a list t val optional: 'at-> 'a option t val skip: 'at-> unit t val no 'at-> unit t val between: unit t -> unit t -> 'at-> 'at val satisfy: (char -> bool) -> chart val satisfy many: (char -> bool) -> string t val accept char: char> char t val accept_string: string -> string t val eof: unit t val spaces: unit t val lexeme: 'at->'at val symbol: string -> unit t val keyword among: string list -> string -> unit t (**[identifier_except] takes a list of keywords and fails if the current identifier is one of the keywords") val identifier except: string list -> string t (** [digits] only allows "0" or a number character sequence not starting with Os *) (** [digits) only allows "0" or a number character sequence not starting with Os *) val digits: string t val int digits: intt val prefix op: 'at-> 'bt->('a-> 'b-> 'b) -> 'bt val right_assoc_op: 'at-> 'bt->('b-> 'a -> 'b-> 'b) -> 'bt val left assoc_op: 'at-> 'bt->('b-> 'a-> 'b -> 'b) -> 'bt val non_assoc_op: 'at-> 'bt-> ('b -> 'a -> 'b -> 'b) -> 'bt end = struct let is digit function '0'.."9' -> true |_ -> false let is nonzero_digit = function '1'.. '9'-> true |->false let is alpha = function 'a'.. "z' | 'A'.. 'Z' -> true |_ -> false let is alphanum c = is_alpha c || is_digit c let is whitespace = function '|'|'|'\n' -> true |_ -> false type input CStream.t type 'a output = 'a option CStream.t type 'at = input -> 'a output exception InvalidKeyword let run pinpCStream.of_string inp >p>fst let of value x fun is ->(Some x, is) let (1) pf fun is0 -> match p is0 with | Some a, is1->faist | None, is1 (None, is1) let (>>>) pq pl"> fun->q let fail fun is ->(None, is) let map fp=pl> fun a> of value (fa) let map2 fpq=pl> fun a-> map (fa) q let map3 fpqr pl> fun a -> map2 (f a) q r let const_map cp map (fun -> c) p let first of 2 p q = fun is -> match p is with None, --> qis |result -> result let rec first of ps= match ps with 10->fail Ipps->first_of_2 p (first of ps) let rec many p = first_of_2 (some p) (of_value []) and some p = p *> fun x -> map (fun xs -> x: xs) (many p) let sep_by_1 p sep=map2 (fun x xs-> x: xs) p (many (sep >> p)) let sep_by p sep=first_of_2 (sep_by_1 p sep) (of_value[]) let optional pfirst_of_2 (map (fun a -> Some a) p) (of_value None) let skip p = map (fun ->()) p let no pfun is -> match p is with | Some a, ->(None, is) | None, ->(Some(), is) let between p1 p2 q = p1 |>> q |*> fun a -> const_map a p2 let satisfy p fun iso-> match CStream.uncons is0 with | None -> (None, is0) Some (c, is1) -> if pc then (Some c, is1) else (None, is0) let satisfy many p= fun is -> let str, rest = CStream.take while p is in (Some str, rest) let accept char c=satisfy (fun c' -> c = c') let accept string s= let len = String.lengths in fun is0 -> match CStream.take len is0 with | None (None, is0) | None (None, is0) | Some (s', is1) -> if s=s' then (Some s, is1) else (None, is0) let eof fun is -> if CStream.is_done is then (Some 0, is) else (None, is) let spaces skip (satisfy_many is_whitespace) (** [lexeme p] runs [p] and consumes all whitespaces after [p] if it succeeds. Otherwise, it backtracks.") let lexeme p = first_of_2 p fail |*> fun a -> const_map a spaces let symbols = lexeme (skip (accept_string s)) let keyword among keywords s if List.mem s keywords then lexeme (accept_string s >> no (satisfy is_alphanum)) else raise InvalidKeyword let identifier except keywords= lexeme (map2 (fun c cs String.make 1 c^cs) (satisfy is_alpha) (satisfy many is_alphanum) *> fun s-> if List.mem s keywords then fail else of value s) let digits= lexeme (first of 2 (const_map "0" (accept_char '0' >> no (satisfy is_digit))) (map2 (func cs-> String.make 1 c ^ cs) (satisfy is nonzero_digit) (satisfy many is_digit))) let int digits=map (fun s->int_of_string s) digits let prefix op operatorp operando con = map2 (function | Some op -> con op | None ->fun a -> a) (optional operatorp) operandp let right assoc_op operatorp operando con = map2 (fun a0 opbs -> List.fold right (fun (op, b) fa-> con a op (fb)) opbs (fun a -> a) a0) operandp (many (map2 (fun op b-> (op, b)) operatorp operandp)) let left_assoc_op operatorp operando con = map2 (List.fold left (fun a (op, b) -> con a op b)) operandp (many (map2 (fun op b-> (op, b)) operatorp operandp)) let non assoc_op operatorp operando con = map2 end (fun a-> function | Some (op, b) -> con a op b | None -> a) operandp (optional (map2 (fun op b-> (ap, b)) operatorp operandp)) A DIY programming language: MiniCAML Note: the prelude for this exercise is quite long. However, we will point you to the useful functions in the prelude when relevant, so you shouldn't try to read it all at once. Note: you must not use references/assignment (=) throughout Project 1 except Part 4. In this project, you will implement a language called MiniML (Project 1) and its extension (Project 2) in OCaml. This project allows you to have deeper operational understanding of the programming language concepts you have seen in the class and to use OCaml for a larger code base. (9)19q 6 tnemelqmi lliw uoy, to9j019 уlementɔsjonq art to tlar tanitairt n 9161602 6 2 2noqmoɔ edit to lɔɔti eqy beɔnsvbs bηs noiлGulv ti zheq 19dto toette ton asob haq s to noitetnemelami pnow s terit prinsem, heq enie169: 169 6 Qnizzɔon to tnioq pnitsta erit,92i19x9 "xibneqqA toejo19" erit ni bedinɔzeb ew 2A .(T2A) 11 xstry tɔsteds ne otni 21911 to eɔneupee 6 pnimotans11 zi opsugel emez ert ebivong ew,919H.210tibe hielt i 19ɔrlɔ to eɔneupe 69th 21mm610019 erit not tuo ti xloriɔ eeselq oz 92iɔ19x9 erit ni 26 29vitiming erit anistoɔ terit 192169 9lubom zevitiming ezert to aquoivaried to alisteb .2wollot 26 JMADiniM to 16mmene erit worle ew Je multiplicative_exp=multiplicative_exp "*" negation_exp (* Left associative binary op **) ❘negation_exp additive_exp = additive_exp "+" multiplicative_exp (* Left associative binary op + *) | additive_exp"-" multiplicative_exp (* Left associative binary op - *) multiplicative_exp comparative exp = additive_exp *=* additive_exp (* Non-associative binary op = *) additive_exp "<" additive_exp (* Non-associative binary op <*) additive_exp exp=comparative_exp", comparative_exp ("Non-associative binary operation pair construction (comma) *) comparative_exp (eqyt egetni *) "ni" qyt imots (eqyt neeloo8*) "lood" | (* eqyt besizeriƒ9169) "("sqyƒ ")" | (* eqyt i69 *) qyt_oimote "*" qyt imots = qytisq qyt oimote Here, (eqyt noitonut .e.i,eqyt wonA *) qyt "<" qyt_sq = qyt qyt isq| "ount" axe imots "921st"| (*ount Instanɔ loo8 *) (salst instanoɔ neeloo8") (* 1619getni *) atigib (*zeldsinsV*) tnebi (*noizz0qxe besizern9169 *) "(" que ")" | (*noitsɔilqqs noitonut evitsiɔ0226 te*) qxe_ɔimots" "qxe_evitsɔilqq6=: qxe_evitilqq qx9_ǝimote (*enibnid smmoɔ tej") "bn" qxe "ni" qxe "=" "(" tnebi Jnobi ")" "tel" qxo_oldstepon (*enibrid te*) "bne" qxe "ni" qxe "=" tnebi "tel" | qxe "eale" qxe "nerd" qxe "t"| qxe "<=" [qyt":"] tnebi "nt" | (* noizz1qxe ezle-nerij- *) sqyt lanoitqo ritiw noitonu *) means that things inside it are optional, e.g. both fn x => x and fn x: int > x are valid for the grammar "fn" ident [":" typ] "=>" exp. We show the grammar for typ for completeness, but note that the parser typ_parser for typ is already provided in the prelude. Your task is to implement the parser exp_parser_impl. For this, you may need to add helper parsers for each grammar class of expressions. Note: you may see an error like This kind of expression is not allowed as right-hand side of 'let rec'. This is due to OCaml's recursion checker. This can happens if you use exp_parser_impl in a recursion instead of exp_parser. In that case, please replace exp_parser_impl calls with exp_parser calls Hint: if your parser does not terminate, It is quite likely due to how you parse additive_exp or multiplicative_exp. Parser.left assoc_op may help you to fix that. FINISH CODE: (Part1: Parsing") let rec typ_parser = let open Parser in let keyword= let keywords=["int"; "bool"] in keyword among keywords (*noitstonns in eqyt lsnoitqo ritiw noiauɔeя ") qx9 "<=" [qyt":"] tabi "391" fun I -> (*noitstonns qxe_evisǝlqq (* - 690 16v xite19 *) qxe_eldstegen ["-"] = qxe_noitsgen let atom typ_parser = first of [const_map Int (keyword "int"); const map Bool (keyword "boal"); between (symbol "(") (symbol ")") typ_parser ] in www_image wwwer prwy www.11 between (symbol "(") (symbol ")") typ_parser let pair_typ_parser = in non_assoc_op (symbol "*") atom_typ_parser (fun t1 () t2 -> Pair (t1, t2)) let typ_parser_impl = in right_assoc_op (symbol "->") pair_typ_parser (fun t1 () t2 -> Arrow (t1, t2)) typ_parser_impli (Part 1: Parsing *) let parse_exp_tests: (string exp option) list = [ ] ("", None) let rec exp_parser i = let open Parser in (** Use [identifier] and [keyword] in your implementation, not [identifier_except] and [keyword among] directly *) let identifier, keyword = let keywords=["true"; "false"; "let"; "in"; "end"; "if"; "then"; "else"; "fn"; "rec"] in identifier_except keywords, keyword_among keywords in (** You may need to define helper parsers depending on [exp_parser] here *) 1:32 PM

Microsoft Visual C#
7th Edition
ISBN:9781337102100
Author:Joyce, Farrell.
Publisher:Joyce, Farrell.
Chapter10: Introduction To Inheritance
Section: Chapter Questions
Problem 13RQ
icon
Related questions
Question

Can you plz help me understand this with the answers, I need help in details. thanks a lot

Prelude Code:
exception Notimplemented
exception ParserFailure
(** MiniCAML Language Definition")
(*Types in MiniCAML *)
type typ=
Int
|Bool
(int)
(bool)
| Pair of typ*typ (*11*12*)
| Arrow of typ "typ (* 11 -> 12*)
(*We extend types with type variables to support type inference.
༄།
Note that this does not have any surface syntax,
and is used only for internal processing.
| TVar of typ option ref
(*Used for identifiers of variables *)
type ident string
(*The binary operations available in MiniCAML *)
type bop=
Equals (e1=2")
| Less Than ("e1<e2*)
Plus (e1e2")
Minus e1-e2*)
Times (e102*)
| Fn of ident*typ option * exp
(* fn x:t=2 e or fn x = 0 *)
| Apply of exp exp
(*01 02*)
| Rec of ident*typ option * exp
(recf: t>e or rec f>e")
Let of ident* exp exp
(*let x e1 in e2 end")
(*x*)
| Var of ident
("Charater Stream")
module CStream: sig
type t
val of string: string->t
val is donet-> bool
val unconst-> (char *t) option
val take: int ->t-> (string *t) option
val take while (char -> bool) ->t> string t
end = struct
type t={input: string; len: int; index: int}
let of strings = {input = s; len = String.length s; index = 0}
let is done cscs.len = cs.index
let uncons cs=
if is done cs
then None
else Some (cs.input.[cs.index], {cs with index = cs.index + 1})
MiniCAML")
let take | cs=
("The unary operations available
type uop=
| Negate (e)
(*Expressions in MiniCAML")
type exp=
Constl of int
PrimBop of exp*bop* exp
| PrimUop of uop exp
| Constẞ of bool
If of exp*exp* exp
(-2-101|2|...")
("e1 <op> 02*)
(* <op> e*)
(* true | false *)
(if e then e1 else e2")
("e1, e2*)
| LetComma of ident ident exp exp (let (x, y) = e1 in e2 end")
Comma of exp* exp
let index = cs.index + 1 in
if index <=cs.len
then Some (String.sub cs.input cs.index I, {cs with index })
else None
let take while pcs =
let rec find_index i =
in
ifi>=cs.len || not (p cs.input.[i])
then i
else find index (i + 1)
let index = find_index cs.index in
(String.sub cs.input cs.index (index - cs.index), {cs with index })
end
(*Parser Primitives/Utilities *)
module Parser sig
type input
type 'a output
type 'at = input -> 'a output
exception InvalidKeyword
val run: 'at -> string -> 'a option
val of value: 'a-> 'at
(read this as "and then" ")
val()'at-> ('a -> 'b t) -> 'bt
(read this as "before" )
val (>>)'at-> 'bt-> 'bt
val fail: 'a t
val map: ('a-> 'b) -> 'at -> 'bt
val map2: ('a -> 'b-> 'c) -> 'at-> 'bt-> 'ct
val map3: ('a -> 'b-> 'c-> 'd) ->'at-> 'bt->'ct->'dt
val const_map: 'b-> 'at-> 'bt
val first_of_2: 'at-> 'at-> 'at
val first of: 'at list -> 'at
val many 'at-> 'a list t
val some: 'at -> 'a list t
val sep_by:'at-> 'bt-> 'a list t
val sep_by_1: "at-> 'bt-> 'a list t
val optional: 'at-> 'a option t
val skip: 'at-> unit t
val no 'at-> unit t
val between: unit t -> unit t -> 'at-> 'at
val satisfy: (char -> bool) -> chart
val satisfy many: (char -> bool) -> string t
val accept char: char> char t
val accept_string: string -> string t
val eof: unit t
val spaces: unit t
val lexeme: 'at->'at
val symbol: string -> unit t
val keyword among: string list -> string -> unit t
(**[identifier_except] takes a list of keywords and fails if the current identifier is one of the
keywords")
val identifier except: string list -> string t
(** [digits] only allows "0" or a number character sequence not starting with Os *)
(** [digits) only allows "0" or a number character sequence not starting with Os *)
val digits: string t
val int digits: intt
val prefix op: 'at-> 'bt->('a-> 'b-> 'b) -> 'bt
val right_assoc_op: 'at-> 'bt->('b-> 'a -> 'b-> 'b) -> 'bt
val left assoc_op: 'at-> 'bt->('b-> 'a-> 'b -> 'b) -> 'bt
val non_assoc_op: 'at-> 'bt-> ('b -> 'a -> 'b -> 'b) -> 'bt
end = struct
let is digit function '0'.."9' -> true |_ -> false
let is nonzero_digit = function '1'.. '9'-> true |->false
let is alpha = function 'a'.. "z' | 'A'.. 'Z' -> true |_ -> false
let is alphanum c = is_alpha c || is_digit c
let is whitespace = function '|'|'|'\n' -> true |_ -> false
type input CStream.t
type 'a output = 'a option CStream.t
type 'at = input -> 'a output
exception InvalidKeyword
let run pinpCStream.of_string inp >p>fst
let of value x fun is ->(Some x, is)
let (1) pf fun is0 ->
match p is0 with
| Some a, is1->faist
| None, is1 (None, is1)
let (>>>) pq pl"> fun->q
let fail fun is ->(None, is)
let map fp=pl> fun a> of value (fa)
let map2 fpq=pl> fun a-> map (fa) q
let map3 fpqr pl> fun a -> map2 (f a) q r
let const_map cp map (fun -> c) p
let first of 2 p q = fun is ->
match p is with
None, --> qis
|result -> result
let rec first of ps=
match ps with
10->fail
Ipps->first_of_2 p (first of ps)
let rec many p = first_of_2 (some p) (of_value [])
and some p = p *> fun x -> map (fun xs -> x: xs) (many p)
let sep_by_1 p sep=map2 (fun x xs-> x: xs) p (many (sep >> p))
let sep_by p sep=first_of_2 (sep_by_1 p sep) (of_value[])
let optional pfirst_of_2 (map (fun a -> Some a) p) (of_value None)
let skip p = map (fun ->()) p
let no pfun is ->
match p is with
| Some a, ->(None, is)
| None,
->(Some(), is)
let between p1 p2 q = p1 |>> q |*> fun a -> const_map a p2
let satisfy p fun iso->
match CStream.uncons is0 with
| None -> (None, is0)
Some (c, is1) ->
if pc
then (Some c, is1)
else (None, is0)
let satisfy many p=
fun is ->
let str, rest = CStream.take while p is in
(Some str, rest)
let accept char c=satisfy (fun c' -> c = c')
let accept string s=
let len = String.lengths in
fun is0 ->
match CStream.take len is0 with
| None (None, is0)
| None
(None, is0)
| Some (s', is1) ->
if s=s'
then (Some s, is1)
else (None, is0)
let eof fun is ->
if CStream.is_done is
then (Some 0, is)
else (None, is)
let spaces skip (satisfy_many is_whitespace)
(** [lexeme p] runs [p] and
consumes all whitespaces after [p] if it succeeds.
Otherwise, it backtracks.")
let lexeme p = first_of_2 p fail |*> fun a -> const_map a spaces
let symbols = lexeme (skip (accept_string s))
let keyword among keywords s
if List.mem s keywords
then lexeme (accept_string s >> no (satisfy is_alphanum))
else raise InvalidKeyword
let identifier except keywords=
lexeme
(map2
(fun c cs String.make 1 c^cs)
(satisfy is_alpha)
(satisfy many is_alphanum)
*> fun s->
if List.mem s keywords
then fail
else of value s)
let digits=
lexeme
(first of 2
(const_map "0" (accept_char '0' >> no (satisfy is_digit)))
(map2
(func cs-> String.make 1 c ^ cs)
(satisfy is nonzero_digit)
(satisfy many is_digit)))
let int digits=map (fun s->int_of_string s) digits
let prefix op operatorp operando con =
map2
(function
| Some op -> con op
| None ->fun a -> a)
(optional operatorp)
operandp
let right assoc_op operatorp operando con =
map2
(fun a0 opbs -> List.fold right (fun (op, b) fa-> con a op (fb)) opbs (fun a -> a) a0)
operandp
(many (map2 (fun op b-> (op, b)) operatorp operandp))
let left_assoc_op operatorp operando con =
map2
(List.fold left (fun a (op, b) -> con a op b))
operandp
(many (map2 (fun op b-> (op, b)) operatorp operandp))
let non assoc_op operatorp operando con =
map2
end
(fun a->
function
| Some (op, b) -> con a op b
| None -> a)
operandp
(optional (map2 (fun op b-> (ap, b)) operatorp operandp))
A DIY programming language: MiniCAML
Note: the prelude for this exercise is quite long. However, we will point you to the useful
functions in the prelude when relevant, so you shouldn't try to read it all at once.
Note: you must not use references/assignment (=) throughout Project 1 except Part 4.
In this project, you will implement a language called MiniML (Project 1) and its extension
(Project 2) in OCaml. This project allows you to have deeper operational understanding of
the programming language concepts you have seen in the class and to use OCaml for a
larger code base.
(9)19q 6 tnemelqmi lliw uoy, to9j019 уlementɔsjonq art to tlar tanitairt n
9161602 6 2 2noqmoɔ edit to lɔɔti eqy beɔnsvbs bηs noiлGulv ti
zheq 19dto toette ton asob haq s to noitetnemelami pnow s terit prinsem, heq
enie169: 169
6 Qnizzɔon to tnioq pnitsta erit,92i19x9 "xibneqqA toejo19" erit ni bedinɔzeb ew 2A
.(T2A) 11 xstry tɔsteds ne otni 21911 to eɔneupee 6 pnimotans11 zi opsugel
emez ert ebivong ew,919H.210tibe hielt i 19ɔrlɔ to eɔneupe 69th 21mm610019
erit not tuo ti xloriɔ eeselq oz 92iɔ19x9 erit ni 26 29vitiming erit anistoɔ terit 192169 9lubom
zevitiming ezert to aquoivaried to alisteb
.2wollot 26 JMADiniM to 16mmene erit worle ew Je
multiplicative_exp=multiplicative_exp "*" negation_exp (* Left associative binary op **)
❘negation_exp
additive_exp = additive_exp "+" multiplicative_exp (* Left associative binary op + *)
| additive_exp"-" multiplicative_exp (* Left associative binary op - *)
multiplicative_exp
comparative exp = additive_exp *=* additive_exp (* Non-associative binary op = *)
additive_exp "<" additive_exp (* Non-associative binary op <*)
additive_exp
exp=comparative_exp", comparative_exp ("Non-associative binary operation pair
construction (comma) *)
comparative_exp
(eqyt egetni *) "ni" qyt imots
(eqyt neeloo8*) "lood" |
(* eqyt besizeriƒ9169) "("sqyƒ ")" |
(* eqyt i69 *) qyt_oimote "*" qyt imots = qytisq
qyt oimote
Here,
(eqyt noitonut .e.i,eqyt wonA *) qyt "<" qyt_sq = qyt
qyt isq|
"ount" axe imots
"921st"|
(*ount Instanɔ loo8 *)
(salst instanoɔ neeloo8")
(* 1619getni *) atigib
(*zeldsinsV*) tnebi
(*noizz0qxe besizern9169 *) "(" que ")" |
(*noitsɔilqqs noitonut evitsiɔ0226 te*) qxe_ɔimots" "qxe_evitsɔilqq6=: qxe_evitilqq
qx9_ǝimote
(*enibnid smmoɔ tej") "bn" qxe "ni" qxe "=" "(" tnebi Jnobi ")" "tel" qxo_oldstepon
(*enibrid te*)
"bne" qxe "ni" qxe "=" tnebi "tel" |
qxe "eale" qxe "nerd" qxe "t"|
qxe "<=" [qyt":"] tnebi "nt" |
(* noizz1qxe ezle-nerij- *)
sqyt lanoitqo ritiw noitonu *)
means that things inside it are optional, e.g. both fn x => x and fn x: int > x are
valid for the grammar "fn" ident [":" typ] "=>" exp.
We show the grammar for typ for completeness, but note that the parser typ_parser for typ
is already provided in the prelude. Your task is to implement the parser exp_parser_impl. For
this, you may need to add helper parsers for each grammar class of expressions.
Note: you may see an error like This kind of expression is not allowed as right-hand side of
'let rec'. This is due to OCaml's recursion checker. This can happens if you use
exp_parser_impl in a recursion instead of exp_parser. In that case, please replace
exp_parser_impl calls with exp_parser calls
Hint: if your parser does not terminate, It is quite likely due to how you parse additive_exp or
multiplicative_exp. Parser.left assoc_op may help you to fix that.
FINISH CODE:
(Part1: Parsing")
let rec typ_parser =
let open Parser in
let keyword=
let keywords=["int"; "bool"] in
keyword among keywords
(*noitstonns
in
eqyt lsnoitqo ritiw noiauɔeя ")
qx9 "<=" [qyt":"] tabi "391"
fun I ->
(*noitstonns
qxe_evisǝlqq
(* - 690 16v xite19 *) qxe_eldstegen ["-"] = qxe_noitsgen
let atom typ_parser =
first of
[const_map Int (keyword "int");
const map Bool (keyword "boal");
between (symbol "(") (symbol ")") typ_parser
]
in
www_image wwwer prwy www.11
between (symbol "(") (symbol ")") typ_parser
let pair_typ_parser =
in
non_assoc_op (symbol "*") atom_typ_parser (fun t1 () t2 -> Pair (t1, t2))
let typ_parser_impl =
in
right_assoc_op (symbol "->") pair_typ_parser (fun t1 () t2 -> Arrow (t1, t2))
typ_parser_impli
(Part 1: Parsing *)
let parse_exp_tests: (string exp option) list = [
]
("", None)
let rec exp_parser i =
let open Parser in
(** Use [identifier] and [keyword] in your implementation,
not [identifier_except] and [keyword among] directly *)
let identifier, keyword =
let keywords=["true"; "false"; "let"; "in"; "end"; "if"; "then"; "else"; "fn"; "rec"] in
identifier_except keywords, keyword_among keywords
in
(** You may need to define helper parsers depending on [exp_parser] here *)
1:32 PM
Transcribed Image Text:Prelude Code: exception Notimplemented exception ParserFailure (** MiniCAML Language Definition") (*Types in MiniCAML *) type typ= Int |Bool (int) (bool) | Pair of typ*typ (*11*12*) | Arrow of typ "typ (* 11 -> 12*) (*We extend types with type variables to support type inference. ༄། Note that this does not have any surface syntax, and is used only for internal processing. | TVar of typ option ref (*Used for identifiers of variables *) type ident string (*The binary operations available in MiniCAML *) type bop= Equals (e1=2") | Less Than ("e1<e2*) Plus (e1e2") Minus e1-e2*) Times (e102*) | Fn of ident*typ option * exp (* fn x:t=2 e or fn x = 0 *) | Apply of exp exp (*01 02*) | Rec of ident*typ option * exp (recf: t>e or rec f>e") Let of ident* exp exp (*let x e1 in e2 end") (*x*) | Var of ident ("Charater Stream") module CStream: sig type t val of string: string->t val is donet-> bool val unconst-> (char *t) option val take: int ->t-> (string *t) option val take while (char -> bool) ->t> string t end = struct type t={input: string; len: int; index: int} let of strings = {input = s; len = String.length s; index = 0} let is done cscs.len = cs.index let uncons cs= if is done cs then None else Some (cs.input.[cs.index], {cs with index = cs.index + 1}) MiniCAML") let take | cs= ("The unary operations available type uop= | Negate (e) (*Expressions in MiniCAML") type exp= Constl of int PrimBop of exp*bop* exp | PrimUop of uop exp | Constẞ of bool If of exp*exp* exp (-2-101|2|...") ("e1 <op> 02*) (* <op> e*) (* true | false *) (if e then e1 else e2") ("e1, e2*) | LetComma of ident ident exp exp (let (x, y) = e1 in e2 end") Comma of exp* exp let index = cs.index + 1 in if index <=cs.len then Some (String.sub cs.input cs.index I, {cs with index }) else None let take while pcs = let rec find_index i = in ifi>=cs.len || not (p cs.input.[i]) then i else find index (i + 1) let index = find_index cs.index in (String.sub cs.input cs.index (index - cs.index), {cs with index }) end (*Parser Primitives/Utilities *) module Parser sig type input type 'a output type 'at = input -> 'a output exception InvalidKeyword val run: 'at -> string -> 'a option val of value: 'a-> 'at (read this as "and then" ") val()'at-> ('a -> 'b t) -> 'bt (read this as "before" ) val (>>)'at-> 'bt-> 'bt val fail: 'a t val map: ('a-> 'b) -> 'at -> 'bt val map2: ('a -> 'b-> 'c) -> 'at-> 'bt-> 'ct val map3: ('a -> 'b-> 'c-> 'd) ->'at-> 'bt->'ct->'dt val const_map: 'b-> 'at-> 'bt val first_of_2: 'at-> 'at-> 'at val first of: 'at list -> 'at val many 'at-> 'a list t val some: 'at -> 'a list t val sep_by:'at-> 'bt-> 'a list t val sep_by_1: "at-> 'bt-> 'a list t val optional: 'at-> 'a option t val skip: 'at-> unit t val no 'at-> unit t val between: unit t -> unit t -> 'at-> 'at val satisfy: (char -> bool) -> chart val satisfy many: (char -> bool) -> string t val accept char: char> char t val accept_string: string -> string t val eof: unit t val spaces: unit t val lexeme: 'at->'at val symbol: string -> unit t val keyword among: string list -> string -> unit t (**[identifier_except] takes a list of keywords and fails if the current identifier is one of the keywords") val identifier except: string list -> string t (** [digits] only allows "0" or a number character sequence not starting with Os *) (** [digits) only allows "0" or a number character sequence not starting with Os *) val digits: string t val int digits: intt val prefix op: 'at-> 'bt->('a-> 'b-> 'b) -> 'bt val right_assoc_op: 'at-> 'bt->('b-> 'a -> 'b-> 'b) -> 'bt val left assoc_op: 'at-> 'bt->('b-> 'a-> 'b -> 'b) -> 'bt val non_assoc_op: 'at-> 'bt-> ('b -> 'a -> 'b -> 'b) -> 'bt end = struct let is digit function '0'.."9' -> true |_ -> false let is nonzero_digit = function '1'.. '9'-> true |->false let is alpha = function 'a'.. "z' | 'A'.. 'Z' -> true |_ -> false let is alphanum c = is_alpha c || is_digit c let is whitespace = function '|'|'|'\n' -> true |_ -> false type input CStream.t type 'a output = 'a option CStream.t type 'at = input -> 'a output exception InvalidKeyword let run pinpCStream.of_string inp >p>fst let of value x fun is ->(Some x, is) let (1) pf fun is0 -> match p is0 with | Some a, is1->faist | None, is1 (None, is1) let (>>>) pq pl"> fun->q let fail fun is ->(None, is) let map fp=pl> fun a> of value (fa) let map2 fpq=pl> fun a-> map (fa) q let map3 fpqr pl> fun a -> map2 (f a) q r let const_map cp map (fun -> c) p let first of 2 p q = fun is -> match p is with None, --> qis |result -> result let rec first of ps= match ps with 10->fail Ipps->first_of_2 p (first of ps) let rec many p = first_of_2 (some p) (of_value []) and some p = p *> fun x -> map (fun xs -> x: xs) (many p) let sep_by_1 p sep=map2 (fun x xs-> x: xs) p (many (sep >> p)) let sep_by p sep=first_of_2 (sep_by_1 p sep) (of_value[]) let optional pfirst_of_2 (map (fun a -> Some a) p) (of_value None) let skip p = map (fun ->()) p let no pfun is -> match p is with | Some a, ->(None, is) | None, ->(Some(), is) let between p1 p2 q = p1 |>> q |*> fun a -> const_map a p2 let satisfy p fun iso-> match CStream.uncons is0 with | None -> (None, is0) Some (c, is1) -> if pc then (Some c, is1) else (None, is0) let satisfy many p= fun is -> let str, rest = CStream.take while p is in (Some str, rest) let accept char c=satisfy (fun c' -> c = c') let accept string s= let len = String.lengths in fun is0 -> match CStream.take len is0 with | None (None, is0) | None (None, is0) | Some (s', is1) -> if s=s' then (Some s, is1) else (None, is0) let eof fun is -> if CStream.is_done is then (Some 0, is) else (None, is) let spaces skip (satisfy_many is_whitespace) (** [lexeme p] runs [p] and consumes all whitespaces after [p] if it succeeds. Otherwise, it backtracks.") let lexeme p = first_of_2 p fail |*> fun a -> const_map a spaces let symbols = lexeme (skip (accept_string s)) let keyword among keywords s if List.mem s keywords then lexeme (accept_string s >> no (satisfy is_alphanum)) else raise InvalidKeyword let identifier except keywords= lexeme (map2 (fun c cs String.make 1 c^cs) (satisfy is_alpha) (satisfy many is_alphanum) *> fun s-> if List.mem s keywords then fail else of value s) let digits= lexeme (first of 2 (const_map "0" (accept_char '0' >> no (satisfy is_digit))) (map2 (func cs-> String.make 1 c ^ cs) (satisfy is nonzero_digit) (satisfy many is_digit))) let int digits=map (fun s->int_of_string s) digits let prefix op operatorp operando con = map2 (function | Some op -> con op | None ->fun a -> a) (optional operatorp) operandp let right assoc_op operatorp operando con = map2 (fun a0 opbs -> List.fold right (fun (op, b) fa-> con a op (fb)) opbs (fun a -> a) a0) operandp (many (map2 (fun op b-> (op, b)) operatorp operandp)) let left_assoc_op operatorp operando con = map2 (List.fold left (fun a (op, b) -> con a op b)) operandp (many (map2 (fun op b-> (op, b)) operatorp operandp)) let non assoc_op operatorp operando con = map2 end (fun a-> function | Some (op, b) -> con a op b | None -> a) operandp (optional (map2 (fun op b-> (ap, b)) operatorp operandp)) A DIY programming language: MiniCAML Note: the prelude for this exercise is quite long. However, we will point you to the useful functions in the prelude when relevant, so you shouldn't try to read it all at once. Note: you must not use references/assignment (=) throughout Project 1 except Part 4. In this project, you will implement a language called MiniML (Project 1) and its extension (Project 2) in OCaml. This project allows you to have deeper operational understanding of the programming language concepts you have seen in the class and to use OCaml for a larger code base. (9)19q 6 tnemelqmi lliw uoy, to9j019 уlementɔsjonq art to tlar tanitairt n 9161602 6 2 2noqmoɔ edit to lɔɔti eqy beɔnsvbs bηs noiлGulv ti zheq 19dto toette ton asob haq s to noitetnemelami pnow s terit prinsem, heq enie169: 169 6 Qnizzɔon to tnioq pnitsta erit,92i19x9 "xibneqqA toejo19" erit ni bedinɔzeb ew 2A .(T2A) 11 xstry tɔsteds ne otni 21911 to eɔneupee 6 pnimotans11 zi opsugel emez ert ebivong ew,919H.210tibe hielt i 19ɔrlɔ to eɔneupe 69th 21mm610019 erit not tuo ti xloriɔ eeselq oz 92iɔ19x9 erit ni 26 29vitiming erit anistoɔ terit 192169 9lubom zevitiming ezert to aquoivaried to alisteb .2wollot 26 JMADiniM to 16mmene erit worle ew Je multiplicative_exp=multiplicative_exp "*" negation_exp (* Left associative binary op **) ❘negation_exp additive_exp = additive_exp "+" multiplicative_exp (* Left associative binary op + *) | additive_exp"-" multiplicative_exp (* Left associative binary op - *) multiplicative_exp comparative exp = additive_exp *=* additive_exp (* Non-associative binary op = *) additive_exp "<" additive_exp (* Non-associative binary op <*) additive_exp exp=comparative_exp", comparative_exp ("Non-associative binary operation pair construction (comma) *) comparative_exp (eqyt egetni *) "ni" qyt imots (eqyt neeloo8*) "lood" | (* eqyt besizeriƒ9169) "("sqyƒ ")" | (* eqyt i69 *) qyt_oimote "*" qyt imots = qytisq qyt oimote Here, (eqyt noitonut .e.i,eqyt wonA *) qyt "<" qyt_sq = qyt qyt isq| "ount" axe imots "921st"| (*ount Instanɔ loo8 *) (salst instanoɔ neeloo8") (* 1619getni *) atigib (*zeldsinsV*) tnebi (*noizz0qxe besizern9169 *) "(" que ")" | (*noitsɔilqqs noitonut evitsiɔ0226 te*) qxe_ɔimots" "qxe_evitsɔilqq6=: qxe_evitilqq qx9_ǝimote (*enibnid smmoɔ tej") "bn" qxe "ni" qxe "=" "(" tnebi Jnobi ")" "tel" qxo_oldstepon (*enibrid te*) "bne" qxe "ni" qxe "=" tnebi "tel" | qxe "eale" qxe "nerd" qxe "t"| qxe "<=" [qyt":"] tnebi "nt" | (* noizz1qxe ezle-nerij- *) sqyt lanoitqo ritiw noitonu *) means that things inside it are optional, e.g. both fn x => x and fn x: int > x are valid for the grammar "fn" ident [":" typ] "=>" exp. We show the grammar for typ for completeness, but note that the parser typ_parser for typ is already provided in the prelude. Your task is to implement the parser exp_parser_impl. For this, you may need to add helper parsers for each grammar class of expressions. Note: you may see an error like This kind of expression is not allowed as right-hand side of 'let rec'. This is due to OCaml's recursion checker. This can happens if you use exp_parser_impl in a recursion instead of exp_parser. In that case, please replace exp_parser_impl calls with exp_parser calls Hint: if your parser does not terminate, It is quite likely due to how you parse additive_exp or multiplicative_exp. Parser.left assoc_op may help you to fix that. FINISH CODE: (Part1: Parsing") let rec typ_parser = let open Parser in let keyword= let keywords=["int"; "bool"] in keyword among keywords (*noitstonns in eqyt lsnoitqo ritiw noiauɔeя ") qx9 "<=" [qyt":"] tabi "391" fun I -> (*noitstonns qxe_evisǝlqq (* - 690 16v xite19 *) qxe_eldstegen ["-"] = qxe_noitsgen let atom typ_parser = first of [const_map Int (keyword "int"); const map Bool (keyword "boal"); between (symbol "(") (symbol ")") typ_parser ] in www_image wwwer prwy www.11 between (symbol "(") (symbol ")") typ_parser let pair_typ_parser = in non_assoc_op (symbol "*") atom_typ_parser (fun t1 () t2 -> Pair (t1, t2)) let typ_parser_impl = in right_assoc_op (symbol "->") pair_typ_parser (fun t1 () t2 -> Arrow (t1, t2)) typ_parser_impli (Part 1: Parsing *) let parse_exp_tests: (string exp option) list = [ ] ("", None) let rec exp_parser i = let open Parser in (** Use [identifier] and [keyword] in your implementation, not [identifier_except] and [keyword among] directly *) let identifier, keyword = let keywords=["true"; "false"; "let"; "in"; "end"; "if"; "then"; "else"; "fn"; "rec"] in identifier_except keywords, keyword_among keywords in (** You may need to define helper parsers depending on [exp_parser] here *) 1:32 PM
Expert Solution
steps

Step by step

Solved in 2 steps

Blurred answer
Similar questions
  • SEE MORE QUESTIONS
Recommended textbooks for you
Microsoft Visual C#
Microsoft Visual C#
Computer Science
ISBN:
9781337102100
Author:
Joyce, Farrell.
Publisher:
Cengage Learning,