我希望将FParsec用于类似python的语言,基于缩进.
我知道这必须在lexing阶段完成,但FParsec没有lexing阶段.可以使用FParsec,或者,如何在lexing之后提供它?
PD:我是F#的新手,但在其他语言方面经验丰富
我的AST模型需要携带位置信息(文件名,行,索引).有没有内置的方式来访问这些信息?从参考文档来看,流似乎具有这个位置,但我更喜欢我不需要实现一个虚拟解析器来保存位置,并在任何地方添加它.
提前致谢
是否可以以块为单位向FParsec解析器提交输入?如果没有,是否可以检索输入流的当前结果和未解析部分,以便我可以完成此操作?我正在尝试运行来自的输入块SocketAsyncEventArgs
而不缓冲整个消息.
更新
注意使用的原因SocketAsyncEventArgs
是表示向a发送数据CharStream
可能导致对底层的异步访问Stream
.具体来说,我正在寻找使用循环缓冲区来推送来自套接字的数据.我记得FParsec文档指出Stream
不应该异步访问底层,所以我计划手动控制分块解析.
终极问题:
Stream
传递给我CharStream
吗?这是所有 FParsec 中最令人费解的组合器......
http://www.quanttec.com/fparsec/reference/primitives.html#members.chainl1
...但是在文档中或互联网上的任何网页上都没有关于如何使用它的示例。我有一个左递归解析似乎需要它,但我一生都不知道如何调用它或传递给它什么。
请帮忙 :)
作为后续内容:如何使用fparsec测试正好2个字符?
我需要解析一个字符串,其中包含一对标识符,后跟自由格式文本.我可以很容易地构造一个解析器,它找到了newline形式的标识符,后面跟着一个空格,后面跟着一个空格.与前面的标识符相关联的自由格式文本是标识符之后的所有内容,但不包括下一个标识符.
例如:
AB Now is the
time for all good
men.
CD Four score and seven years ago EF our.
Run Code Online (Sandbox Code Playgroud)
包含两个标识符AB
和CD
两个自由格式文本
Now is the \ntime for all good men.
Four score and seven years ago EF our.
我的问题是我不知道如何构造一个与自由格式文本匹配但不匹配标识符的解析器.这是我需要做回溯的情况吗?
可以这样做,如果是这样的话怎么办?
我正在使用FParsec来解析描述其自己格式的输入.例如,考虑这个输入:
int,str,int:4,'hello',3
Run Code Online (Sandbox Code Playgroud)
输入的第一部分(冒号前)描述了输入的第二部分的格式.在这种情况下,格式是int
,str
,int
,这意味着实际的数据由三个以逗号分隔的给定类型的值,所以结果应该是4
,"hello"
,3
.
使用FParsec解析类似这样的东西的最佳方法是什么?
我已经在下面尽了最大的努力,但我对此并不满意.有没有更好的方法来做到更清洁,更少有状态,更少依赖parse
monad?我认为这取决于UserState的更智能管理,但我不知道该怎么做.谢谢.
open FParsec
type State = { Formats : string[]; Index : int32 }
with static member Default = { Formats = [||]; Index = 0 }
type Value =
| Integer of int
| String of string
let parseFormat : Parser<_, State> =
parse {
let! formats =
sepBy
(pstring "int" <|> pstring "str")
(skipString ",")
|>> Array.ofList
do! updateUserState (fun …
Run Code Online (Sandbox Code Playgroud) 我想解析一些语法,如下所示
OUTPUT data
GROUPBY key
TO location
USING object
Run Code Online (Sandbox Code Playgroud)
子句的顺序GROUPBY TO USING
允许变化,但每个子句最多出现一次。
在 FParsec 中是否有方便或内置的方法来解析它?我读了一些提到 Haskell Parsec 排列的问题和答案。FParsec 中似乎没有排列。如果这是要走的路,我会如何在 FParsec 中构建排列?
我希望使用F#将字符串解析为递归数据结构.在这个问题中,我将提出一个简化的例子,它将切入我想要做的事情的核心.
我想将一串嵌套的方括号解析为记录类型:
type Bracket = | Bracket of Bracket option
Run Code Online (Sandbox Code Playgroud)
所以:
Bracket None
Bracket ( Some ( Bracket None) )
Bracket ( Some ( Bracket ( Some ( Bracket None) ) ) )
我想使用FParsec库中的解析器组合器来完成此操作.这是我到目前为止:
let tryP parser =
parser |>> Some
<|>
preturn None
/// Parses up to nesting level of 3
let parseBrakets : Parser<_> =
let mostInnerLevelBracket =
pchar '['
.>> pchar ']'
|>> fun _ -> Bracket None …
Run Code Online (Sandbox Code Playgroud) 给定输入:
alpha beta gamma one two three
Run Code Online (Sandbox Code Playgroud)
我怎样才能将其解析为下面的内容?
[["alpha"; "beta"; "gamma"]; ["one"; "two"; "three"]]
Run Code Online (Sandbox Code Playgroud)
当有更好的分隔符(例如__)时我可以写这个,就像这样
sepBy (sepBy word (pchar ' ')) (pstring "__")
Run Code Online (Sandbox Code Playgroud)
有效,但在双倍空格的情况下,第一个 sepBy 中的 pchar 消耗第一个空格,然后解析器失败。
考虑以下将数字字符串转换为int
s的解析器:
let toInt (s:string) =
match Int32.TryParse(s) with
| (true, n) -> preturn n
| _ -> fail "Number must be below 2147483648"
let naturalNum = many1Chars digit >>= toInt <?> "natural number"
Run Code Online (Sandbox Code Playgroud)
当我在非数字字符串上运行它时,"abc"
它显示正确的错误消息:
let toInt (s:string) =
match Int32.TryParse(s) with
| (true, n) -> preturn n
| _ -> fail "Number must be below 2147483648"
let naturalNum = many1Chars digit >>= toInt <?> "natural number"
Run Code Online (Sandbox Code Playgroud)
但是,当我给它一个超出int
范围的数字字符串时,它会给出以下适得其反的信息:
Error in Ln: 1 Col: 1
abc …
Run Code Online (Sandbox Code Playgroud)