使用 FParsec 解析变量声明
Parsing a variable declaration with FParsec
我正在尝试使用 FParsec 解析变量声明。我阅读了教程的一部分,以及 Phillip Trelford's example of parsing 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)
但我不知道如何实现我的版本,这看起来更复杂....如果有人可以给我一个线索,或者 link 可以更清楚地解释如何去做,它会对我有很大帮助。
您可以以此为例:
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));"
我正在尝试使用 FParsec 解析变量声明。我阅读了教程的一部分,以及 Phillip Trelford's example of parsing 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)
但我不知道如何实现我的版本,这看起来更复杂....如果有人可以给我一个线索,或者 link 可以更清楚地解释如何去做,它会对我有很大帮助。
您可以以此为例:
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));"