Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 解析项的FParsec和后缀修饰符_Parsing_F#_Fparsec - Fatal编程技术网

Parsing 解析项的FParsec和后缀修饰符

Parsing 解析项的FParsec和后缀修饰符,parsing,f#,fparsec,Parsing,F#,Fparsec,作为我自己的一个练习,我正在使用FParsec编写一个函数,该函数可以从(有限的)正则表达式形式的规范中生成随机字符串 例如 我有很多工作要做,但我对后缀词的概念有点困惑(即解析器可能需要返回并修改输出,而不仅仅是字符流中的位置)。例如“a”对“a+” 以下是我的域类型的精简版本: type Count = | ExactCount of int | MinCount of int | MaxCount of int | RangeCount of int * i

作为我自己的一个练习,我正在使用FParsec编写一个函数,该函数可以从(有限的)正则表达式形式的规范中生成随机字符串

例如

我有很多工作要做,但我对后缀词的概念有点困惑(即解析器可能需要返回并修改输出,而不仅仅是字符流中的位置)。例如“a”对“a+”

以下是我的域类型的精简版本:

type Count =
    | ExactCount of int
    | MinCount of int
    | MaxCount of int
    | RangeCount of int * int

type Term =
    | CharLiteral of char
    | Count of Term * Count

type RandExpSpec = Term list
因此输入
ab
应该生成
[CharLiteral'a';CharLiteral'b']
,但是
ab+
应该生成
[CharLiteral'a';Count(CharLiteral'b',MinCount 1)]
。这意味着,在流中遇到
Count
术语时,解析器需要回溯输出,以便将最后一个术语包装到另一个对象中

现在,我不知道怎么做。以下是我当前的解析定义,它确实(大部分)有效,但效率非常低:

let parseCharLiteral = choice [ letter; digit ] |>> CharLiteral

let rec parseTerm =
    parse.Delay(fun () -> choice [ parseCharLiteral ])

and parseCount =
    parseTerm
    .>>. choice [ skipChar '*' >>% (MinCount 0)
                  skipChar '+' >>% (MinCount 1)
                  skipChar '?' >>% (RangeCount(0, 1)) ]
    |>> Count

let parseTerms =
    many ((attempt parseCount) <|> parseTerm) .>> eof

但是我不能这样做,因为
parseCount
q需要包装
parseTerm

返回的上一个术语,我认为您可以使用
opt
允许
parseCount
在没有计数的情况下不查找计数:

=
语法术语
.>>. 选项(选项[skipChar'*'>>%(最小计数0)
skipChar“+”>>%(最小计数1)
skipChar'?'>>%(范围计数(0,1)))
|>>作用
|术语,无->术语
|术语,某些计数->计数(术语,计数)
让我们来分析术语=
许多parseCount.>>eof
let parseCharLiteral = choice [ letter; digit ] |>> CharLiteral

let rec parseTerm =
    parse.Delay(fun () -> choice [ parseCharLiteral ])

and parseCount =
    parseTerm
    .>>. choice [ skipChar '*' >>% (MinCount 0)
                  skipChar '+' >>% (MinCount 1)
                  skipChar '?' >>% (RangeCount(0, 1)) ]
    |>> Count

let parseTerms =
    many ((attempt parseCount) <|> parseTerm) .>> eof
let parseCharLiteral = choice [ letter; digit ] |>> CharLiteral

let rec parseTerm =
    parse.Delay(fun () -> choice [ parseCharLiteral ] .>>. (attempt parseCount))

and parseCount =
    choice [ skipChar '*' >>% (MinCount 0)
             skipChar '+' >>% (MinCount 1)
             skipChar '?' >>% (RangeCount(0, 1)) ]
    |>> Count

let parseTerms =
    many parseTerm .>> eof