我熟悉fparsec的一些基础知识,但它似乎是面向文本文件或流.
还有其他F#库可以有效地解析二进制文件吗?或者可以轻松修改fparsec以便有效地使用二进制流?
我正在寻找一些用FParsec编写的示例语法,它将超出项目存储库中的示例.
我发现了这个非常好的GLSL语法,但这是我发现的唯一样本.我需要的是一种类似于C或JavaScript的语言的语法.
我决定查看FParsec,并尝试为λ表达式编写解析器.事实证明,渴望使递归解析变得困难.我怎么解决这个问题?
码:
open FParsec
type ?Expr =
| Variable of char
| Application of ?Expr * ?Expr
| Lambda of char * ?Expr
let rec FV = function
| Variable v -> Set.singleton v
| Application (f, x) -> FV f + FV x
| Lambda (x, m) -> FV m - Set.singleton x
let ?0 = FV >> (=) Set.empty
let apply f p =
parse
{ let! v = p
return f v }
let ? e = …
Run Code Online (Sandbox Code Playgroud) 我试图在F#Interactive中运行一些FParsec代码,但没有成功.我能够构建并运行此tutorial.fs
文件,但FSI没有发生同样的情况,因为它无法识别FParsec.dll
.
我已经尝试#r "Parsec"
在FSI中运行该命令,但它无济于事.
有人知道这里可能出现什么问题吗?
我正在尝试使用FParsec从s表达式语言解析lisp样式的注释.我在前一个线程中解析单行注释得到了一些帮助 - 如何将FParsec解析器转换为解析空格
虽然这已经解决了,但我仍然需要解析多行注释.这是当前的代码 -
/// Read whitespace character as a string.
let spaceAsStr = anyOf whitespaceChars |>> fun chr -> string chr
/// Read a line comment.
let lineComment = pchar lineCommentChar >>. restOfLine true
/// Read a multiline comment.
/// TODO: make multiline comments nest.
let multilineComment =
between
(pstring openMultilineCommentStr)
(pstring closeMultilineCommentStr)
(charsTillString closeMultilineCommentStr true System.Int32.MaxValue)
/// Read whitespace text.
let whitespace =
lineComment <|>
multilineComment <|>
spaceAsStr
/// Skip any white space characters.
let skipWhitespace = …
Run Code Online (Sandbox Code Playgroud) 我开始学习FParsec了.它有一种非常灵活的方式来解析数字; 我可以提供一组我想要使用的数字格式:
type Number =
| Numeral of int
| Decimal of float
| Hexadecimal of int
| Binary of int
let numberFormat = NumberLiteralOptions.AllowFraction
||| NumberLiteralOptions.AllowHexadecimal
||| NumberLiteralOptions.AllowBinary
let pnumber =
numberLiteral numberFormat "number"
|>> fun num -> if num.IsHexadecimal then Hexadecimal (int num.String)
elif num.IsBinary then Binary (int num.String)
elif num.IsInteger then Numeral (int num.String)
else Decimal (float num.String)
Run Code Online (Sandbox Code Playgroud)
但是,我试图解析的语言有点奇怪.数字可以是数字(非负int
),十进制(非负float
),十六进制(带前缀#x
)或二进制(带前缀#b
):
numeral: 0, 2
decimal: 0.2, 2.0
hexadecimal: #xA04, #x611ff
binary: …
Run Code Online (Sandbox Code Playgroud) 问题与此类似,但我想使用OperatorPrecedenceParser
in 解析带有函数应用程序的表达式FParsec
.
这是我的AST:
type Expression =
| Float of float
| Variable of VarIdentifier
| BinaryOperation of Operator * Expression * Expression
| FunctionCall of VarIdentifier (*fun name*) * Expression list (*arguments*)
Run Code Online (Sandbox Code Playgroud)
我有以下输入:
board?create_obstacle(4, 4, 450, 0, fric)
Run Code Online (Sandbox Code Playgroud)
这是解析器代码:
let expr = (number |>> Float) <|> (ident |>> Variable)
let parenexpr = between (str_ws "(") (str_ws ")") expr
let opp = new OperatorPrecedenceParser<_,_,_>()
opp.TermParser <- expr <|> parenexpr
opp.AddOperator(InfixOperator("?", ws,
10, Associativity.Right,
fun left …
Run Code Online (Sandbox Code Playgroud) 我是F#的新手并且有一个非常讨厌的问题.我想解析以下语法:
Application := Expression Expression
Expression := "(" "lambda" Name "." Application ")"
| Name
Name := [a-z]+
Run Code Online (Sandbox Code Playgroud)
这将匹配像(lambda x. (lambda y. x y)) z
和的东西(lambda x. x) y
.
我的问题是两个规则相互依赖:
let popen = pchar '('
let pclose = pchar ')'
let pname = many1 letter |>> Seq.toArray |>> System.String |>> NameNode
let plambda = pstring "lambda"
let pdot = pchar '.'
let phead = plambda >>. pname .>> pdot
let pexpression =
popen >>. pname .>>. papplication …
Run Code Online (Sandbox Code Playgroud) 如何在不解析所有输入的情况下检测FParsec解析器何时停止?
例如,以下解析器p
在找到意外字符时停止d
,并且不会继续解析输入的其余部分.
let test p str =
match run p str with
| Success(result, _, _) -> printfn "Success: %A" result
| Failure(errorMsg, s, _) -> printfn "Failure: %s %A" errorMsg s
let str s = pstring s
let a = str "a" .>> spaces
let b = str "b" .>> spaces
let p = many (a <|> b)
test p "ab a d bba " // Success: ["a"; "b"; "a"]
Run Code Online (Sandbox Code Playgroud) 我希望将FParsec用于类似python的语言,基于缩进.
我知道这必须在lexing阶段完成,但FParsec没有lexing阶段.可以使用FParsec,或者,如何在lexing之后提供它?
PD:我是F#的新手,但在其他语言方面经验丰富