我正在尝试编写一个解析器。然而,每当我试图解析替代方案时,我都会遇到堆栈溢出异常。下面是触发此问题的一个示例:
#r @"..\packages\FParsec\lib\net40-client\FParsecCS.dll"
#r @"..\packages\FParsec\lib\net40-client\FParsec.dll"
open FParsec
type Parser<'t> = Parser<'t, unit>
type Element =
| Alternates of Element lis
我想解析一些语法,如下所示
OUTPUT data
GROUPBY key
TO location
USING object
GROUPBY TO USING子句的顺序可以改变,但每个子句最多只能出现一次。
在FParsec中有没有一种方便的或内置的方法来解析它?我读了一些问题和答案,其中提到Haskell Parsec permute。在FParsec中似乎没有置换。如果这是可行的方法,那么我该如何在FParsec中构建置换呢?
我正在尝试使用fparsec和unions (1 + (2 * 3)) //DSL样本输入(递归)来实现以下目标
type AirthmeticExpression =
| Constant of float
| AddNumber of AirthmeticExpression * AirthmeticExpression
| Mul of AirthmeticExpression * AirthmeticExpression
在fparsec中,我有用于Add和Mul as的createParserForwardedToRef
let parseE
下面的示例代码似乎运行得很好:
open FParsec
let capitalized : Parser<unit,unit> =(asciiUpper >>. many asciiLower >>. eof)
let inverted : Parser<unit,unit> =(asciiLower >>. many asciiUpper >>. eof)
let capsOrInvert =choice [capitalized;inverted]
然后你可以:
run capsOrInvert "Dog
我使用FParsec来解析描述自己格式的输入。例如,考虑以下输入:
int,str,int:4,'hello',3
输入的第一部分(冒号之前)描述输入第二部分的格式。在本例中,格式为int、str、int,这意味着实际数据由给定类型的三个逗号分隔的值组成,因此结果应该是4、"hello"、3。
用FParsec解析这样的东西最好的方法是什么?
我已经尽了最大的努力,但我对此并不满意。是否有更好的方法来做到这一点更干净、更少有状态、更少依赖parse?我认为这取决于对UserState的更聪明的管理,但我不知道如何做到这一点。谢谢。
open FParsec
t
我正试图解决编程中最可怕的部分,那就是解析和AST。我正在使用F#和FParsec编写一个简单的示例。我想解析一个简单的乘法系列。不过,我只会得到第一个学期的回报。以下是我到目前为止所拥有的:
open FParsec
let test p str =
match run p str with
| Success(result, _, _) -> printfn "Success: %A" result
| Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg
我目前正在学习FParsec库,但我遇到了一个问题。当我想解析一个可选字符串并在以后继续正常解析时,FParsec将在可选解析器上返回一个致命错误,而不是像我预期的那样返回None。下面的工作代码示例说明了我的观点:
open System
open FParsec
type AccountEntity =
| Default
| Entity of string
let pEntity =
let isEntityFirstChar c = isLetter c
let isEntityChar c = isLetter c || isDigit c
我决定检查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
我需要在使用FParsec的OperatorPrecedenceParsers解析操作符时生成错误,特别是在映射阶段。假设我有以下代码:
let pOperatorExpr : ExpressionParser =
let opp = new OperatorPrecedenceParser<MyType, unit, unit>()
let arithmeticOperator a b ->
if someOperation a b then
// Fatal error! Abort!
else fo
我在尝试用FParsec解析类似json的同构数组时遇到了一个问题。我已经将这个问题分解成一个简短的例子来再现它。
#r @"..\packages\FParsec.1.0.2\lib\net40-client\FParsecCS.dll"
#r @"..\packages\FParsec.1.0.2\lib\net40-client\FParsec.dll"
open System
open FParsec
let test p str =
match run p str with
| Success(result, _,
我有一个用C#完成的手写CSS解析器,它变得难以管理,我试图用FParsec来做它,以使它更易于管理。以下是解析由正则表达式组成的css选择器元素的代码片段:
var tagRegex = @"(?<Tag>(?:[a-zA-Z][_\-0-9a-zA-Z]*|\*))";
var idRegex = @"(?:#(?<Id>[a-zA-Z][_\-0-9a-zA-Z]*))";
var classesRegex = @"(?<Classes>(?:\.[a-zA-Z][_\-0-9a-zA-Z]*)+)";
我正在尝试使用FParsec解析已修复的字符串。例如parsing null from the documentation open FParsec
type Json = JNull
let jnull : Parser<_> = stringReturn "null" JNull 然后在"null"上运行jnull会得到预期的结果 > run jnull "null";;
val it : ParserResult<Json,unit> = Success: JNull 但是如果我在"nulls
我尝试使用3+2,2解析前缀函数,比如Pow( FParsec )。我在示例文件中阅读了计算器教程,如下所示。这些例子都是一元前缀函数。我想知道如何使用FParsec.OperatorPrecedenceParser实现多个输入的前缀函数。
let number = pfloat .>> ws
let opp = new OperatorPrecedenceParser<float,unit,unit>()
let expr = opp.ExpressionParser
opp.TermParser <- number <|> between (s
以前的问题,我不能用这些问题来解决
似乎是在createParserForwardedToRef被添加到FParsec之前提出的一个老问题。
AST似乎没有我的递归得可怕。
语法依赖于一个特殊的字符'['来表示另一个嵌套级别。我没有这种奢侈
我想为我最近写的一种语言建立一种词汇和项目系统。这门语言叫做q。它是一种相当简单的语言,没有运算符优先。例如,1*2+3与(1*(2+3))相同。它的工作有点像反向波兰符号计算器,评估是从右到左。
我很难用FParsec来表达这一点。我已经整理了以下简化演示
open FParsec
type Binary
在没有解析所有输入的情况下,如何检测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 =
我试图用int32解析一个FParsec,但有一个额外的限制,即这个数字必须小于某个最大值。它们是在不编写我自己的自定义解析器(如下面所示)和/或我的自定义解析器(下面)实现需求的适当方式下执行此操作的一种方法。
我之所以这样问,是因为大多数内置库函数似乎都围绕着满足某些谓词而不是任何其他类型的char。
let pRow: Parser<int> =
let error = messageError ("int parsed larger than maxRows")
let mutable res = Reply(Error, error)
我正在为我正在制作的语言进行解析阶段的工作,并且在以下方面遇到了困难。
let test2 = // I'd like this to be an error.
"""
2
+ 2
"""
let result = run (spaces >>. expr) test2
val result : ParserResult<CudaExpr,unit> =
Success: Add (LitInt32 2,LitInt32 2)
当术语缩进不正确时,我已经成功地制作了以下示例
我想用FParsec来解析字符串文字。我所说的“字符串文字”指的是开始引号和结束引号之间的东西(在我的例子中--单引号):
'Please, switch off your mobile phone'
我目前正在做的事情如下:
let string = between (pstring "'") (pstring "'") (manySatisfy isLetter)
但是在消费了第一个字母之后就停止了。有没有办法让它变得贪婪?
我对“真正的解析器”,如F#或Haskell,解析自定义运算符的方式有点纠结。对于“普通”语言,我们只需定义一个可以预定义运算符的AST节点,例如:+,-,*,==,>=,+=,...等。
但我想知道如何在函数式语言中创建自定义运算符,让我们以OCaml为例,非常接近F# (我的实现语言),并且非常著名。
因此,每个运算符都是一个函数,具有类型和定义,我们可以创建自己的运算符:
val (+) : 'a -> 'a -> 'a
let (+) x y = x + y
val (|>) : 'a -> ('a -> &
我已经开始学习FParsec了。它有一种非常灵活的解析数字的方法;我可以提供一组我想使用的数字格式:
type Number =
| Numeral of int
| Decimal of float
| Hexadecimal of int
| Binary of int
let numberFormat = NumberLiteralOptions.AllowFraction
||| NumberLiteralOptions.AllowHexadecimal
||| NumberL