Разбор объявления переменной с помощью FParsec - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь разобрать объявление переменной с помощью FParsec.Я прочитал часть урока, а также пример разбора C # Филиппа Трелфорда.Вот что можно отсканировать:

let [identifier] = [value];
let [identifier] [: type] = [value];
let [identifier] = [new [type(constructor)]];

Например:

let foo = 9;
let foo: Integer = 9;
let foo = new Integer(9);

Но foo также может принимать аргументы, например:

let foo(a, b) = a + b;
let foo(a: Integer, b: Integer = 0) -> Integer = a + b;

В основном, инструкция let идентична команде F #, за исключением того, что аргументы заключены в скобки, а блок отсутствует, есть только выражение.

В учебном пособии реализована переменная C #, такая как:

let pdefine = pipe2 (pidentifier .>> ws1) (pidentifier)
                (fun ty name -> Define(ty,name))

let pdefinition = pdefine |>> fun d -> Definition(d)

Но я понятия не имею, как реализовать мою версию, которая кажется более сложной ... Если кто-то может дать мне руководство или ссылку, которая бы более четко объяснила, как это сделать, этоочень помог бы мне.

1 Ответ

0 голосов
/ 18 октября 2018

Вы можете использовать это как пример:

open FParsec
open System

let str = pstring
let ws = spaces

type VarType = 
    | Implicit
    | Explicit of string

type Value = 
    | IntValue of int
    | TypeConstructor of string * Value

type LetDeclr = LetDeclr of string * VarType * Value

let isValidChar c =
    ['A'..'Z'] @ ['a'..'z']
    |> Seq.exists (fun ch -> ch = c)

let identifierParser = manySatisfy isValidChar

let value, valueRef = createParserForwardedToRef()

do valueRef := choice [
    str "new" >>. ws >>. identifierParser >>= fun typeName ->
        ws >>. between (str "(") (str ")") value |>> fun typeValue ->
             TypeConstructor(typeName, typeValue)
    pint32 |>> IntValue
]

let parser = 
    str "let" >>. ws >>. identifierParser
    >>= fun identifier ->
    attempt (ws >>. str ":" >>. ws >>. identifierParser |>> Explicit) <|> (ws >>% Implicit )
    >>= fun varType ->
    ws >>. str "=" >>. ws >>. value
    |>> fun varValue -> LetDeclr(identifier, varType, varValue)
    .>> ws .>> str ";"

let parse = FParsec.CharParsers.run parser

parse "let foo = 9;"
parse "let foo: Integer = 9;"
parse "let foo = new Integer(new String(344));"
...