Define the named procedure parser
A name procedure consists of three parts:
Wrap everything together
Finally we wrap everything together in a
Finally we create a helper function to parse a file
To simplify the use of our logo parser we finally create a simple function with a single parameter, representing the
A name procedure consists of three parts:
- A
headerthat start with the string "to" followed by anIdentifierand a set ofParameters. - A
bodythat contains one or morepcommandlines. - A
footerthat contains the string "end"
phead, pbody and pfoot parsers, which is tied together using the logical conjunction (AND) operators .>>. and ,>>; the dots (.) indicate which of the parsed output we are holding onto namely:name-- the identifier of the named procedureps-- the parameters of the named procedurebody-- the commands within the named procedure
Procedure; we first update the mutable reference to procs by adding newly identified named procedures and their parameters; follow by an updateCalls() to dynamically generate new procedural call parsers and to also update the mutable reference to the pcall parser; to ensure that the in progress parsing will correctly be able to parse procedural calls to the encountered name procedures.
C#:
let pprocedure =
let pparameters = many (pparameter .>> spaces)
let phead = pstring "to" >>. spaces1 >>. pidentifier .>> spaces1 .>>. pparameters
let pbody = many (pcommand .>> spaces1)
let pfoot = pstring "end"
phead .>>. pbody .>> pfoot
|>> fun ((name, ps), body) ->
procs := (name, ps) :: !procs; updateCalls()
Procedure(name, ps, body)
Wrap everything together
Finally we wrap everything together in a
plogo parser which is a parser that merges a logical disjunction between a parser that can parse a pprocedure and pcommand. The sepEndBy is a combinator that will match an indeterminate number of pprocedure or pcommand parsers separated by 1 or more spaces.
C#:
let plogo = spaces >>. (sepEndBy (pcommand <|> pprocedure) spaces1)
Finally we create a helper function to parse a file
To simplify the use of our logo parser we finally create a simple function with a single parameter, representing the
code we want to parse. Internally we parse the code with the plogo parser and then pattern match over the result; in the case of a Success we return the result; which is the AST, and in the case of a Failure we throw an exception with the error message.
C#:
let parse code =
match run plogo code with
| Success(result, _, _) -> result
| Failure(msg, _, _) -> failwith msg
Last edited:





