88 people like it.
Like the snippet!
Top-Down-Operator-Precedence Parser
F# implementation of a generic Top-Down-Operator-Precedence Parser as described in this paper http://portal.acm.org/citation.cfm?id=512931
Example starts at line ~300
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:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
|
module Parser =
(*
F# implementation of a generic Top-Down-Operator-Precedence Parser
as described in this paper http://portal.acm.org/citation.cfm?id=512931.
The parser has been extended to allow for statements in comparison to Pratt's
original algorithm which only parsed languages which use expression-only grammar.
The parsers is "impure" in the sense that is uses a ref-cell for storing the
input in the T<_, _, _> record class, this is soley for performance reasons
as it's to expensive to create a new record object for every consumed token.
Certain functions also throw exceptions, which generally also is considered impure.
The parser produces nice error message in this style:
Error on line: 5 col: 9
4: if(x == y) {
5: print'x equals y');
----------^
Unexpected: #string "x equals y"
More information:
* http://en.wikipedia.org/wiki/Vaughan_Pratt (Original Inventor)
* http://en.wikipedia.org/wiki/Pratt_parser (Alias name)
* http://effbot.org/zone/simple-top-down-parsing.htm (Python implementation)
* http://javascript.crockford.com/tdop/tdop.html (JavaScript implementation)
*)
type Pos = int * int
type T<'a, 'b, 'c> when 'c : comparison = {
Input : 'a list ref
Lines : string option
Type : 'a -> 'c
Position : 'a -> Pos
PrettyPrint : ('a -> string) option
//Parser definitions and binding powers
BindingPower : Map<'c, int>
Null : Map<'c, 'a -> T<'a, 'b, 'c> -> 'b>
Stmt : Map<'c, 'a -> T<'a, 'b, 'c> -> 'b>
Left : Map<'c, 'a -> 'b -> T<'a, 'b, 'c> -> 'b>
}
type Pattern<'a, 'b, 'c> when 'c : comparison
= Sym of 'c
| Get of (T<'a, 'b, 'c> -> 'b)
//Errors
type Exn (msg, pos) =
inherit System.Exception(msg)
member x.Position = pos
(*
Creates a string error snippet
that points out the exact source position
where the error occured, for example:
4: if(x == y) {
5: print'x equals y');
----------^
*)
let errorSource pos source =
let splitLines (text:string) =
let text = text.Replace("\r\n", "\n").Replace("\r", "\n")
System.Text.RegularExpressions.Regex.Split(text, "\n")
let lineNum (input:int) n =
(input.ToString()).PadLeft(n, '0')
let stringRepeat n input =
if System.String.IsNullOrEmpty input then input
else
let result = new System.Text.StringBuilder(input.Length * n)
result.Insert(0, input, n).ToString()
match source with
| None -> ""
| Some(source:string) ->
let source = source |> splitLines
let result = ref ""
let line, column = pos
if line <= source.Length && line > 1 then
let nr = line.ToString()
let nrl = nr.Length
//previous line
let pline = line - 1
if pline >= 1 then
let num = lineNum pline nrl
result := num+": "+source.[pline-1]+"\n"
//current line
let text = source.[line-1]
if column <= text.Length then
let arrow = "-" |> stringRepeat (nrl + column)
result := !result+nr+": "+text+"\n"+arrow+"^\n"
!result
let exn msg = Exn(msg, (0, 0)) |> raise
let exnLine pos msg =
let line = sprintf "Error on line: %i col: %i\n" (fst pos) (snd pos)
Exn(line + msg, pos) |> raise
let private unexpectedEnd () = "Unexpected end of input" |> exn
let private unexpectedToken token parser =
let type' =
match parser.PrettyPrint with
| None -> (token |> parser.Type).ToString()
| Some f -> token |> f
let pos = token |> parser.Position
let source = parser.Lines |> errorSource pos
let expected = sprintf "Unexpected: %s" type'
(source + expected) |> exnLine pos
let inline private getBindingPower tok parser =
let pwr = parser.BindingPower.TryFind (parser.Type tok)
match pwr with Some pwr -> pwr | _ -> 0
let current parser =
match !parser.Input with
| token::_ -> token
| _ -> unexpectedEnd ()
let currentTry parser =
match !parser.Input with
| token::_ -> Some token
| _ -> None
let currentType parser =
parser |> current |> parser.Type
let currentTypeTry parser =
match parser |> currentTry with
| Some token -> Some(token |> parser.Type)
| _ -> None
let skip parser =
match !parser.Input with
| _::input -> parser.Input := input
| _ -> unexpectedEnd ()
let skipIf type' parser =
match !parser.Input with
| token::xs when parser.Type token = type' ->
parser.Input := xs
| token::_ ->
unexpectedToken token parser
| _ -> unexpectedEnd ()
let skipCurrent parser =
let current = parser |> current
parser |> skip
current
let exprPwr rbpw parser =
let rec expr left =
match parser |> currentTry with
| Some token when rbpw < (parser |> getBindingPower token) ->
parser |> skip
let type' = parser.Type token
let led = parser.Left.[type']
led token left parser |> expr
| _ -> left
let tok = parser |> skipCurrent
expr (parser.Null.[parser.Type tok] tok parser)
let expr parser =
parser |> exprPwr 0
let exprSkip type' parser =
let expr = parser |> expr
parser |> skipIf type'
expr
let rec exprList parser =
match !parser.Input with
| [] -> []
| _ -> (parser |> expr) :: (parser |> exprList)
let stmt term parser =
let token = parser |> current
match parser.Stmt.TryFind (token |> parser.Type) with
| Some stmt -> parser |> skip; stmt token parser
| None -> parser |> exprSkip term
let rec stmtList term parser =
match !parser.Input with
| [] -> []
| _ -> (parser |> stmt term) :: (parser |> stmtList term)
let match' pattern parser =
let rec match' acc pattern parser =
match pattern with
| [] -> acc |> List.rev
| Sym(symbol)::pattern ->
parser |> skipIf symbol
parser |> match' acc pattern
| Get(f)::pattern ->
let acc = (f parser) :: acc
parser |> match' acc pattern
parser |> match' [] pattern
let matchError () =
exn "Match pattern failed"
let create<'a, 'b, 'c when 'c : comparison> type' pos string = {
Input = ref []
Lines = None
Type = type'
Position = pos
PrettyPrint = string
BindingPower = Map.empty<'c, int>
Null = Map.empty<'c, 'a -> T<'a, 'b, 'c> -> 'b>
Stmt = Map.empty<'c, 'a -> T<'a, 'b, 'c> -> 'b>
Left = Map.empty<'c, 'a -> 'b -> T<'a, 'b, 'c> -> 'b>
}
let smd token funct parser = {parser with T.Stmt = parser.Stmt.Add(token, funct)}
let nud token funct parser = {parser with T.Null = parser.Null.Add(token, funct)}
let led token funct parser = {parser with T.Left = parser.Left.Add(token, funct)}
let bpw token power parser = {parser with T.BindingPower = parser.BindingPower.Add(token, power)}
let runExpr input source parser =
{parser with
T.Input = ref input
T.Lines = source
} |> exprList
let runStmt input source term parser =
{parser with
T.Input = ref input
T.Lines = source
} |> stmtList term
(*
Example parser for a very simple grammar
*)
//AST Types
type UnaryOp
= Plus
| Minus
type BinaryOp
= Multiply
| Add
| Subtract
| Divide
| Assign
| Equals
type Ast
= Number of int
| Identifier of string
| String of string
| Binary of BinaryOp * Ast * Ast
| Unary of UnaryOp * Ast
| Ternary of Ast * Ast * Ast // test * ifTrue * ifFalse
| If of Ast * Ast * Ast option // test + ifTrue and possibly ifFalse (else branch)
| Call of Ast * Ast list // target + arguments list
| Block of Ast list // statements list
| True
| False
//Shorthand types for convenience
module P = Parser
type Token = string * string * (Parser.Pos)
type P = Parser.T<Token, Ast, string>
//Utility functions for extracting values out of Token
let type' ((t, _, _):Token) = t
let value ((_, v, _):Token) = v
let pos ((_, _, p):Token) = p
let value_num (t:Token) = t |> value |> int
//Utility functions for creating new tokens
let number value pos : Token = "#number", value, pos
let string value pos : Token = "#string", value, pos
let identifier name pos : Token = "#identifier", name, pos
let symbol type' pos : Token = type', "", pos
let add = symbol "+"
let sub = symbol "-"
let mul = symbol "*"
let div = symbol "/"
let assign = symbol "="
let equals = symbol "=="
let lparen = symbol "("
let rparen = symbol ")"
let lbrace = symbol "{"
let rbrace = symbol "}"
let comma = symbol ","
let qmark = symbol "?"
let colon = symbol ":"
let scolon = symbol ";"
let if' = symbol "if"
let true' = symbol "true"
let else' = symbol "else"
//Utility functions for converting tokens to binary and unary operators
let toBinaryOp tok =
match type' tok with
| "=" -> BinaryOp.Assign
| "+" -> BinaryOp.Add
| "-" -> BinaryOp.Subtract
| "*" -> BinaryOp.Multiply
| "/" -> BinaryOp.Divide
| "==" -> BinaryOp.Equals
| _ -> P.exn (sprintf "Couldn't convert %s-token to BinaryOp" (type' tok))
let toUnaryOp tok =
match type' tok with
| "+" -> UnaryOp.Plus
| "-" -> UnaryOp.Minus
| _ -> P.exn (sprintf "Couldn't convert %s-token to UnaryOp" (type' tok))
//Utility function for defining infix operators
let infix typ pwr p =
let infix tok left (p:P) =
Binary(tok |> toBinaryOp, left, p |> P.exprPwr pwr)
p |> P.bpw typ pwr |> P.led typ infix
//Utility function for defining prefix operators
let prefix typ p =
let prefix tok (p:P) =
Unary(tok |> toUnaryOp, p |> P.exprPwr 70)
p |> P.nud typ prefix
//Utility function for defining constants
let constant typ value p =
p |> P.nud typ (fun _ _ -> value)
//Utility function for parsing a block
let block p =
let rec stmts p =
match p |> P.currentTypeTry with
| None -> []
| Some "}" -> p |> P.skip; []
| _ -> (p |> P.stmt ";") :: (stmts p)
p |> P.skipIf "{"
Block(p |> stmts)
//Pretty printing function for error messages
let prettyPrint (tok:Token) =
match tok with
| "#number", value, _ -> sprintf "#number %s" value
| "#identifier", name, _ -> sprintf "#identifier %s" name
| "#string", value, _ -> sprintf "#string \"%s\"" value
| type', _, _ -> type'
//The parser definition
let example_parser =
(P.create type' pos (Some prettyPrint))
//Literals and identifiers
|> P.nud "#number" (fun t _ -> t |> value |> int |> Number)
|> P.nud "#identifier" (fun t _ -> t |> value |> Identifier)
|> P.nud "#string" (fun t _ -> t |> value |> String)
//Constants
|> constant "true" Ast.True
|> constant "false" Ast.False
//Infix Operators <expr> <op> <expr>
|> infix "==" 40
|> infix "+" 50
|> infix "-" 50
|> infix "*" 60
|> infix "/" 60
|> infix "=" 80
//Prefix Operators <op> <expr>
|> prefix "+"
|> prefix "-"
//Grouping expressions (<expr>)
|> P.nud "(" (fun t p -> p |> P.exprSkip ")")
//Ternary operator <expr> ? <expr> : <expr>
|> P.bpw "?" 70
|> P.led "?" (fun _ left p ->
let ternary = [P.Get P.expr; P.Sym ":"; P.Get P.expr]
match p |> P.match' ternary with
| ifTrue::ifFalse::_ -> Ternary(left, ifTrue, ifFalse)
| _ -> P.matchError()
)
//If/Else statement if(<condition>) { <exprs } [else { <exprs> }]
|> P.smd "if" (fun _ p ->
let if' = [P.Sym "("; P.Get P.expr; P.Sym ")"; P.Get block]
let else' = [P.Sym "else"; P.Get block]
match p |> P.match' if' with
| test::ifTrue::_ ->
match p |> P.match' else' with
| ifFalse::_ -> If(test, ifTrue, Some(ifFalse))
| _ -> If(test, ifTrue, None)
| _ -> P.matchError()
)
//Function call
|> P.bpw "(" 80
|> P.led "(" (fun _ func p ->
let rec args (p:P) =
match p |> P.currentType with
| ")" -> p |> P.skip; []
| "," -> p |> P.skip; args p
| _ -> (p |> P.expr) :: args p
Call(func, args p)
)
//Code to parse
(*
1: x = 5;
2: y = 5;
3:
4: if(x == y) {
5: print("x equals y");
6: } else {
7: print("x doesn't equal y");
8: }
*)
let code = @"x = 5;
y = 5;
if(x == y) {
print('x equals y');
} else {
print('x doesn't equal y');
}"
//The code in tokens, manually entered
//since we don't have a lexer to produce
//the tokens for us
let tokens =
[
//x = 5;
identifier "x" (1, 1)
assign (1, 3)
number "5" (1, 5)
scolon (1, 6)
//y = 5;
identifier "y" (2, 1)
assign (2, 3)
number "5" (2, 5)
scolon (2, 6)
//if(x == y) {
if' (4, 1)
lparen (4, 3)
identifier "x" (4, 4)
equals (4, 6)
identifier "y" (4, 9)
rparen (4, 10)
lbrace (4, 12)
//print("x equals y");
identifier "print" (5, 3)
lparen (5, 8)
string "x equals y" (5, 9)
rparen (5, 21)
scolon (5, 22)
//} else {
rbrace (6, 1)
else' (6, 3)
lbrace (6, 7)
//print("x doesn't equal y");
identifier "print" (7, 3)
lparen (7, 7)
string "x doesn't equal y" (7, 9)
rparen (7, 27)
scolon (7, 28)
//}
rbrace (8, 1)
]
let ast = example_parser |> P.runStmt tokens (Some code) ";"
|
type Pos = int * int
Full name: Script.Parser.Pos
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
type T<'a,'b,'c (requires comparison)> =
{Input: 'a list ref;
Lines: string option;
Type: 'a -> 'c;
Position: 'a -> Pos;
PrettyPrint: ('a -> string) option;
BindingPower: Map<'c,int>;
Null: Map<'c,('a -> T<'a,'b,'c> -> 'b)>;
Stmt: Map<'c,('a -> T<'a,'b,'c> -> 'b)>;
Left: Map<'c,('a -> 'b -> T<'a,'b,'c> -> 'b)>;}
Full name: Script.Parser.T<_,_,_>
T.Input: 'a list ref
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
Multiple items
val ref : value:'T -> 'T ref
Full name: Microsoft.FSharp.Core.Operators.ref
--------------------
type 'T ref = Ref<'T>
Full name: Microsoft.FSharp.Core.ref<_>
T.Lines: string option
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
T.Type: 'a -> 'c
T.Position: 'a -> Pos
T.PrettyPrint: ('a -> string) option
T.BindingPower: Map<'c,int>
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
T.Null: Map<'c,('a -> T<'a,'b,'c> -> 'b)>
T.Stmt: Map<'c,('a -> T<'a,'b,'c> -> 'b)>
T.Left: Map<'c,('a -> 'b -> T<'a,'b,'c> -> 'b)>
type Pattern<'a,'b,'c (requires comparison)> =
| Sym of 'c
| Get of (T<'a,'b,'c> -> 'b)
Full name: Script.Parser.Pattern<_,_,_>
union case Pattern.Sym: 'c -> Pattern<'a,'b,'c>
union case Pattern.Get: (T<'a,'b,'c> -> 'b) -> Pattern<'a,'b,'c>
Multiple items
type Exn =
inherit Exception
new : msg:string * pos:(int * int) -> Exn
member Position : int * int
Full name: Script.Parser.Exn
--------------------
new : msg:string * pos:(int * int) -> Exn
val msg : string
val pos : int * int
namespace System
Multiple items
type Exception =
new : unit -> Exception + 2 overloads
member Data : IDictionary
member GetBaseException : unit -> Exception
member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
member GetType : unit -> Type
member HelpLink : string with get, set
member InnerException : Exception
member Message : string
member Source : string with get, set
member StackTrace : string
...
Full name: System.Exception
--------------------
System.Exception() : unit
System.Exception(message: string) : unit
System.Exception(message: string, innerException: exn) : unit
System.Exception(info: System.Runtime.Serialization.SerializationInfo, context: System.Runtime.Serialization.StreamingContext) : unit
val x : Exn
member Exn.Position : int * int
Full name: Script.Parser.Exn.Position
val errorSource : int * int -> source:string option -> string
Full name: Script.Parser.errorSource
val source : string option
val splitLines : (string -> string [])
val text : string
System.String.Replace(oldValue: string, newValue: string) : string
System.String.Replace(oldChar: char, newChar: char) : string
namespace System.Text
namespace System.Text.RegularExpressions
Multiple items
type Regex =
new : pattern:string -> Regex + 1 overload
member GetGroupNames : unit -> string[]
member GetGroupNumbers : unit -> int[]
member GroupNameFromNumber : i:int -> string
member GroupNumberFromName : name:string -> int
member IsMatch : input:string -> bool + 1 overload
member Match : input:string -> Match + 2 overloads
member Matches : input:string -> MatchCollection + 1 overload
member Options : RegexOptions
member Replace : input:string * replacement:string -> string + 5 overloads
...
Full name: System.Text.RegularExpressions.Regex
--------------------
System.Text.RegularExpressions.Regex(pattern: string) : unit
System.Text.RegularExpressions.Regex(pattern: string, options: System.Text.RegularExpressions.RegexOptions) : unit
System.Text.RegularExpressions.Regex.Split(input: string, pattern: string) : string []
System.Text.RegularExpressions.Regex.Split(input: string, pattern: string, options: System.Text.RegularExpressions.RegexOptions) : string []
val lineNum : (int -> int -> string)
val input : int
val n : int
System.Int32.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
val stringRepeat : (int -> string -> string)
val input : string
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
System.String(value: nativeptr<char>) : unit
System.String(value: nativeptr<sbyte>) : unit
System.String(value: char []) : unit
System.String(c: char, count: int) : unit
System.String(value: nativeptr<char>, startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
System.String(value: char [], startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: System.Text.Encoding) : unit
System.String.IsNullOrEmpty(value: string) : bool
val result : System.Text.StringBuilder
Multiple items
type StringBuilder =
new : unit -> StringBuilder + 5 overloads
member Append : value:string -> StringBuilder + 18 overloads
member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
member AppendLine : unit -> StringBuilder + 1 overload
member Capacity : int with get, set
member Chars : int -> char with get, set
member Clear : unit -> StringBuilder
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EnsureCapacity : capacity:int -> int
member Equals : sb:StringBuilder -> bool
...
Full name: System.Text.StringBuilder
--------------------
System.Text.StringBuilder() : unit
System.Text.StringBuilder(capacity: int) : unit
System.Text.StringBuilder(value: string) : unit
System.Text.StringBuilder(value: string, capacity: int) : unit
System.Text.StringBuilder(capacity: int, maxCapacity: int) : unit
System.Text.StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
property System.String.Length: int
System.Text.StringBuilder.Insert(index: int, value: obj) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: uint64) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: uint32) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: uint16) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: decimal) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: float) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: float32) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: int64) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: int) : System.Text.StringBuilder
(+0 other overloads)
System.Text.StringBuilder.Insert(index: int, value: char []) : System.Text.StringBuilder
(+0 other overloads)
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
val source : string
val source : string []
val result : string ref
val line : int
val column : int
property System.Array.Length: int
val nr : string
val nrl : int
val pline : int
val num : string
val arrow : string
Multiple items
val exn : msg:string -> 'a
Full name: Script.Parser.exn
--------------------
type exn = System.Exception
Full name: Microsoft.FSharp.Core.exn
val raise : exn:System.Exception -> 'T
Full name: Microsoft.FSharp.Core.Operators.raise
val exnLine : int * int -> msg:string -> 'a
Full name: Script.Parser.exnLine
val line : string
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val fst : tuple:('T1 * 'T2) -> 'T1
Full name: Microsoft.FSharp.Core.Operators.fst
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
val private unexpectedEnd : unit -> 'a
Full name: Script.Parser.unexpectedEnd
val private unexpectedToken : token:'a -> parser:T<'a,'b,'c> -> 'd (requires comparison)
Full name: Script.Parser.unexpectedToken
val token : 'a
val parser : T<'a,'b,'c> (requires comparison)
val type' : string
val f : ('a -> string)
val pos : Pos
val expected : string
val private getBindingPower : tok:'a -> parser:T<'a,'b,'c> -> int (requires comparison)
Full name: Script.Parser.getBindingPower
val tok : 'a
val pwr : int option
member Map.TryFind : key:'Key -> 'Value option
val pwr : int
val current : parser:T<'a,'b,'c> -> 'a (requires comparison)
Full name: Script.Parser.current
val currentTry : parser:T<'a,'b,'c> -> 'a option (requires comparison)
Full name: Script.Parser.currentTry
val currentType : parser:T<'a,'b,'c> -> 'c (requires comparison)
Full name: Script.Parser.currentType
val currentTypeTry : parser:T<'a,'b,'c> -> 'c option (requires comparison)
Full name: Script.Parser.currentTypeTry
val skip : parser:T<'a,'b,'c> -> unit (requires comparison)
Full name: Script.Parser.skip
val input : 'a list
val skipIf : type':'a -> parser:T<'b,'c,'a> -> unit (requires comparison)
Full name: Script.Parser.skipIf
val type' : 'a (requires comparison)
val parser : T<'b,'c,'a> (requires comparison)
T.Input: 'b list ref
val token : 'b
val xs : 'b list
T.Type: 'b -> 'a
val skipCurrent : parser:T<'a,'b,'c> -> 'a (requires comparison)
Full name: Script.Parser.skipCurrent
val current : 'a
val exprPwr : rbpw:int -> parser:T<'a,'b,'c> -> 'b (requires comparison)
Full name: Script.Parser.exprPwr
val rbpw : int
val expr : ('b -> 'b)
val left : 'b
val type' : 'c (requires comparison)
val led : ('a -> 'b -> T<'a,'b,'c> -> 'b) (requires comparison)
val expr : parser:T<'a,'b,'c> -> 'b (requires comparison)
Full name: Script.Parser.expr
val exprSkip : type':'a -> parser:T<'b,'c,'a> -> 'c (requires comparison)
Full name: Script.Parser.exprSkip
val expr : 'c
val exprList : parser:T<'a,'b,'c> -> 'b list (requires comparison)
Full name: Script.Parser.exprList
val stmt : term:'a -> parser:T<'b,'c,'a> -> 'c (requires comparison)
Full name: Script.Parser.stmt
val term : 'a (requires comparison)
T.Stmt: Map<'a,('b -> T<'b,'c,'a> -> 'c)>
val stmt : ('b -> T<'b,'c,'a> -> 'c) (requires comparison)
val stmtList : term:'a -> parser:T<'b,'c,'a> -> 'c list (requires comparison)
Full name: Script.Parser.stmtList
val match' : pattern:Pattern<'a,'b,'c> list -> parser:T<'a,'b,'c> -> 'b list (requires comparison)
Full name: Script.Parser.match'
val pattern : Pattern<'a,'b,'c> list (requires comparison)
val match' : ('d list -> Pattern<'e,'d,'f> list -> T<'e,'d,'f> -> 'd list) (requires comparison)
val acc : 'd list
val pattern : Pattern<'e,'d,'f> list (requires comparison)
val parser : T<'e,'d,'f> (requires comparison)
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val rev : list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.rev
val symbol : 'f (requires comparison)
val f : (T<'e,'d,'f> -> 'd) (requires comparison)
val matchError : unit -> 'a
Full name: Script.Parser.matchError
val create : type':('a -> 'c) -> pos:('a -> Pos) -> string:('a -> string) option -> T<'a,'b,'c> (requires comparison)
Full name: Script.Parser.create
val type' : ('a -> 'c) (requires comparison)
val pos : ('a -> Pos)
Multiple items
val string : ('a -> string) option
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
val empty<'Key,'T (requires comparison)> : Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.empty
val smd : token:'a -> funct:('b -> T<'b,'c,'a> -> 'c) -> parser:T<'b,'c,'a> -> T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.smd
val token : 'a (requires comparison)
val funct : ('b -> T<'b,'c,'a> -> 'c) (requires comparison)
member Map.Add : key:'Key * value:'Value -> Map<'Key,'Value>
val nud : token:'a -> funct:('b -> T<'b,'c,'a> -> 'c) -> parser:T<'b,'c,'a> -> T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.nud
T.Null: Map<'a,('b -> T<'b,'c,'a> -> 'c)>
val led : token:'a -> funct:('b -> 'c -> T<'b,'c,'a> -> 'c) -> parser:T<'b,'c,'a> -> T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.led
val funct : ('b -> 'c -> T<'b,'c,'a> -> 'c) (requires comparison)
T.Left: Map<'a,('b -> 'c -> T<'b,'c,'a> -> 'c)>
val bpw : token:'a -> power:int -> parser:T<'b,'c,'a> -> T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.bpw
val power : int
T.BindingPower: Map<'a,int>
val runExpr : input:'a list -> source:string option -> parser:T<'a,'b,'c> -> 'b list (requires comparison)
Full name: Script.Parser.runExpr
val runStmt : input:'a list -> source:string option -> term:'b -> parser:T<'a,'c,'b> -> 'c list (requires comparison)
Full name: Script.Parser.runStmt
val term : 'b (requires comparison)
val parser : T<'a,'c,'b> (requires comparison)
type UnaryOp =
| Plus
| Minus
Full name: Script.UnaryOp
union case UnaryOp.Plus: UnaryOp
union case UnaryOp.Minus: UnaryOp
type BinaryOp =
| Multiply
| Add
| Subtract
| Divide
| Assign
| Equals
Full name: Script.BinaryOp
union case BinaryOp.Multiply: BinaryOp
union case BinaryOp.Add: BinaryOp
union case BinaryOp.Subtract: BinaryOp
union case BinaryOp.Divide: BinaryOp
union case BinaryOp.Assign: BinaryOp
union case BinaryOp.Equals: BinaryOp
type Ast =
| Number of int
| Identifier of string
| String of string
| Binary of BinaryOp * Ast * Ast
| Unary of UnaryOp * Ast
| Ternary of Ast * Ast * Ast
| If of Ast * Ast * Ast option
| Call of Ast * Ast list
| Block of Ast list
| True
...
Full name: Script.Ast
union case Ast.Number: int -> Ast
union case Ast.Identifier: string -> Ast
Multiple items
union case Ast.String: string -> Ast
--------------------
module String
from Microsoft.FSharp.Core
union case Ast.Binary: BinaryOp * Ast * Ast -> Ast
union case Ast.Unary: UnaryOp * Ast -> Ast
union case Ast.Ternary: Ast * Ast * Ast -> Ast
union case Ast.If: Ast * Ast * Ast option -> Ast
union case Ast.Call: Ast * Ast list -> Ast
union case Ast.Block: Ast list -> Ast
union case Ast.True: Ast
union case Ast.False: Ast
module Parser
from Script
type Token = string * string * Parser.Pos
Full name: Script.Token
type P = Parser.T<Token,Ast,string>
Full name: Script.P
val type' : string * string * Parser.Pos -> string
Full name: Script.type'
val t : string
val value : string * string * Parser.Pos -> string
Full name: Script.value
val v : string
val pos : string * string * Parser.Pos -> Parser.Pos
Full name: Script.pos
val p : Parser.Pos
val value_num : string * string * Parser.Pos -> int
Full name: Script.value_num
val t : Token
val number : value:string -> int * int -> Token
Full name: Script.number
val value : string
val pos : Parser.Pos
Multiple items
val string : value:string -> int * int -> Token
Full name: Script.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
val identifier : name:string -> int * int -> Token
Full name: Script.identifier
val name : string
val symbol : type':string -> int * int -> Token
Full name: Script.symbol
val add : (Parser.Pos -> Token)
Full name: Script.add
val sub : (Parser.Pos -> Token)
Full name: Script.sub
val mul : (Parser.Pos -> Token)
Full name: Script.mul
val div : (Parser.Pos -> Token)
Full name: Script.div
val assign : (Parser.Pos -> Token)
Full name: Script.assign
val equals : (Parser.Pos -> Token)
Full name: Script.equals
val lparen : (Parser.Pos -> Token)
Full name: Script.lparen
val rparen : (Parser.Pos -> Token)
Full name: Script.rparen
val lbrace : (Parser.Pos -> Token)
Full name: Script.lbrace
val rbrace : (Parser.Pos -> Token)
Full name: Script.rbrace
val comma : (Parser.Pos -> Token)
Full name: Script.comma
val qmark : (Parser.Pos -> Token)
Full name: Script.qmark
val colon : (Parser.Pos -> Token)
Full name: Script.colon
val scolon : (Parser.Pos -> Token)
Full name: Script.scolon
val if' : (Parser.Pos -> Token)
Full name: Script.if'
val true' : (Parser.Pos -> Token)
Full name: Script.true'
val else' : (Parser.Pos -> Token)
Full name: Script.else'
val toBinaryOp : string * string * Parser.Pos -> BinaryOp
Full name: Script.toBinaryOp
val tok : Token
val exn : msg:string -> 'a
Full name: Script.Parser.exn
val toUnaryOp : string * string * Parser.Pos -> UnaryOp
Full name: Script.toUnaryOp
val infix : typ:string -> pwr:int -> p:Parser.T<Token,Ast,string> -> Parser.T<Token,Ast,string>
Full name: Script.infix
val typ : string
val p : Parser.T<Token,Ast,string>
val infix : (Token -> Ast -> P -> Ast)
val left : Ast
val p : P
val exprPwr : rbpw:int -> parser:Parser.T<'a,'b,'c> -> 'b (requires comparison)
Full name: Script.Parser.exprPwr
val bpw : token:'a -> power:int -> parser:Parser.T<'b,'c,'a> -> Parser.T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.bpw
val led : token:'a -> funct:('b -> 'c -> Parser.T<'b,'c,'a> -> 'c) -> parser:Parser.T<'b,'c,'a> -> Parser.T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.led
val prefix : typ:string -> p:Parser.T<Token,Ast,string> -> Parser.T<Token,Ast,string>
Full name: Script.prefix
val prefix : (Token -> P -> Ast)
val nud : token:'a -> funct:('b -> Parser.T<'b,'c,'a> -> 'c) -> parser:Parser.T<'b,'c,'a> -> Parser.T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.nud
val constant : typ:'a -> value:'b -> p:Parser.T<'c,'b,'a> -> Parser.T<'c,'b,'a> (requires comparison)
Full name: Script.constant
val typ : 'a (requires comparison)
val value : 'b
val p : Parser.T<'c,'b,'a> (requires comparison)
val block : p:Parser.T<'a,Ast,string> -> Ast
Full name: Script.block
val p : Parser.T<'a,Ast,string>
val stmts : (Parser.T<'b,'c,string> -> 'c list)
val p : Parser.T<'b,'c,string>
val currentTypeTry : parser:Parser.T<'a,'b,'c> -> 'c option (requires comparison)
Full name: Script.Parser.currentTypeTry
val skip : parser:Parser.T<'a,'b,'c> -> unit (requires comparison)
Full name: Script.Parser.skip
val stmt : term:'a -> parser:Parser.T<'b,'c,'a> -> 'c (requires comparison)
Full name: Script.Parser.stmt
val skipIf : type':'a -> parser:Parser.T<'b,'c,'a> -> unit (requires comparison)
Full name: Script.Parser.skipIf
val prettyPrint : string * string * Parser.Pos -> string
Full name: Script.prettyPrint
val example_parser : Parser.T<Token,Ast,string>
Full name: Script.example_parser
val create : type':('a -> 'c) -> pos:('a -> Parser.Pos) -> string:('a -> string) option -> Parser.T<'a,'b,'c> (requires comparison)
Full name: Script.Parser.create
val exprSkip : type':'a -> parser:Parser.T<'b,'c,'a> -> 'c (requires comparison)
Full name: Script.Parser.exprSkip
val ternary : Parser.Pattern<'a,'b,string> list
union case Parser.Pattern.Get: (Parser.T<'a,'b,'c> -> 'b) -> Parser.Pattern<'a,'b,'c>
val expr : parser:Parser.T<'a,'b,'c> -> 'b (requires comparison)
Full name: Script.Parser.expr
union case Parser.Pattern.Sym: 'c -> Parser.Pattern<'a,'b,'c>
val match' : pattern:Parser.Pattern<'a,'b,'c> list -> parser:Parser.T<'a,'b,'c> -> 'b list (requires comparison)
Full name: Script.Parser.match'
val ifTrue : Ast
val ifFalse : Ast
val smd : token:'a -> funct:('b -> Parser.T<'b,'c,'a> -> 'c) -> parser:Parser.T<'b,'c,'a> -> Parser.T<'b,'c,'a> (requires comparison)
Full name: Script.Parser.smd
val if' : Parser.Pattern<'a,Ast,string> list
val else' : Parser.Pattern<'a,Ast,string> list
val test : Ast
val func : Ast
val args : (P -> Ast list)
val currentType : parser:Parser.T<'a,'b,'c> -> 'c (requires comparison)
Full name: Script.Parser.currentType
val code : string
Full name: Script.code
val tokens : Token list
Full name: Script.tokens
val ast : Ast list
Full name: Script.ast
val runStmt : input:'a list -> source:string option -> term:'b -> parser:Parser.T<'a,'c,'b> -> 'c list (requires comparison)
Full name: Script.Parser.runStmt
More information