Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would highly recommend the F# language as your language of choice for parsing on the .NET Platform. It's roots in the ML family of languages means it has excellent support for language-oriented programming.</p> <p>Discriminated unions and pattern-matching allow for a very succinct and powerful specification of your AST. Higher-order functions allow for definition of parse operations and their composition. First-class support for monadic types allows for state management to be handled implicitly greatly simplifying the composition of parsers. Powerful type-inference greatly aides the definition of these (complex) types. And all of this can be specified and executed interactively allowing you to rapidly prototype.</p> <p>Stephan Tolksdorf has put this into practice with his parser combinator library <a href="http://www.quanttec.com/fparsec/" rel="noreferrer">FParsec</a></p> <p>From his examples we see how naturally an AST is specified:</p> <pre><code>type expr = | Val of string | Int of int | Float of float | Decr of expr type stmt = | Assign of string * expr | While of expr * stmt | Seq of stmt list | IfThen of expr * stmt | IfThenElse of expr * stmt * stmt | Print of expr type prog = Prog of stmt list </code></pre> <p>the implementation of the parser (partially elided) is just as succinct:</p> <pre><code>let stmt, stmtRef = createParserForwardedToRef() let stmtList = sepBy1 stmt (ch ';') let assign = pipe2 id (str ":=" &gt;&gt;. expr) (fun id e -&gt; Assign(id, e)) let print = str "print" &gt;&gt;. expr |&gt;&gt; Print let pwhile = pipe2 (str "while" &gt;&gt;. expr) (str "do" &gt;&gt;. stmt) (fun e s -&gt; While(e, s)) let seq = str "begin" &gt;&gt;. stmtList .&gt;&gt; str "end" |&gt;&gt; Seq let ifthen = pipe3 (str "if" &gt;&gt;. expr) (str "then" &gt;&gt;. stmt) (opt (str "else" &gt;&gt;. stmt)) (fun e s1 optS2 -&gt; match optS2 with | None -&gt; IfThen(e, s1) | Some s2 -&gt; IfThenElse(e, s1, s2)) do stmtRef:= choice [ifthen; pwhile; seq; print; assign] let prog = ws &gt;&gt;. stmtList .&gt;&gt; eof |&gt;&gt; Prog </code></pre> <p>On the second line, as an example, <code>stmt</code> and <code>ch</code> are parsers and <code>sepBy1</code> is a monadic parser combinator that takes two simple parsers and returns a combination parser. In this case <code>sepBy1 p sep</code> returns a parser that parses one or more occurrences of <code>p</code> separated by <code>sep</code>. You can thus see how quickly a powerful parser can be combined from simple parsers. F#'s support for overridden operators also allow for concise infix notation e.g. the sequencing combinator and the choice combinator can be specified as <code>&gt;&gt;.</code> and <code>&lt;|&gt;</code>.</p> <p>Best of luck,</p> <p>Danny</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload