Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.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 如何在使用F#FsYacc进行解析时添加和使用自定义上下文参数?_Parsing_F#_Fsyacc - Fatal编程技术网

Parsing 如何在使用F#FsYacc进行解析时添加和使用自定义上下文参数?

Parsing 如何在使用F#FsYacc进行解析时添加和使用自定义上下文参数?,parsing,f#,fsyacc,Parsing,F#,Fsyacc,我在F#应用程序中使用FsLex和FsYacc进行字符串解析。在抽象语法树(AST)创建过程中,解析器必须决定如何创建AST(生成不同的树、抛出异常等)。 解析器的行为必须依赖于几个参数 我发现可以声明如下内容: %type < (context -> context) > toplevel %type上下文)>顶级 但是我找不到如何使用这个构造,在项目编译期间,我已经退出了“fsyacc.exe”,代码为1 问题是:在使用FsYacc进行解析时,是否可能以及如何使用上下文

我在F#应用程序中使用FsLex和FsYacc进行字符串解析。在抽象语法树(AST)创建过程中,解析器必须决定如何创建AST(生成不同的树、抛出异常等)。 解析器的行为必须依赖于几个参数

我发现可以声明如下内容:

%type < (context -> context) > toplevel
%type<(上下文->上下文)>顶级
但是我找不到如何使用这个构造,在项目编译期间,我已经退出了“fsyacc.exe”,代码为1

问题是:在使用FsYacc进行解析时,是否可能以及如何使用上下文参数

我尝试过的例子:

%start startAst

%type < (bool -> MyAst) > startAst

%%   

startAst:
| MyAst EOF { 
                    (fun (x : bool) -> 
                        if x then 
                            MyAst.Type1 $1 
                        else 
                            MyAst.Type2) 
                }
...
%启动startAst
%类型<(bool->MyAst)>startAst
%%   
startAst:
|MyAst EOF{
(乐趣(x:bool)->
如果x那么
MyAst.Type1$1
其他的
MyAst.Type2)
}
...
我期望使用类似这样的用法:

let lexbuf = Lexing.LexBuffer<char>.FromString text
lexbuf |> Lexer.tokenize |> Parser.startAst (ctx: bool)
让lexbuf=Lexing.LexBuffer.FromString text
lexbuf |>Lexer.tokenize |>Parser.startAst(ctx:bool)
提前谢谢

更新在fsyacc.exe执行期间生成以下异常和调用堆栈:

Unhandled Exception: System.Exception: more than one input given
   at FSharp.PowerPack.FsYacc.Driver.clo@67-5.Invoke(String x)
   at <StartupCode$fsyacc>.$Arg.findMatchingArg$cont@104-1(FSharpRef`1 cursor, FSharpFunc`2 other, String usageText, FSharpList`1 argSpecs, String arg, Unit unitVar)
   at <StartupCode$fsyacc>.$Arg.findMatchingArg@64(FSharpRef`1 cursor, String[] argv, FSharpFunc`2 other, String usageText, Int32 nargs, FSharpList`1 argSpecs, String arg, FSharpList`1 args)
   at Internal.Utilities.ArgParser.ParsePartial(FSharpRef`1 cursor, String[] argv, IEnumerable`1 arguments, FSharpOption`1 otherArgs, FSharpOption`1 usageText)
   at Internal.Utilities.ArgParser.Parse(IEnumerable`1 arguments, FSharpOption`1 otherArgs, FSharpOption`1 usageText)
   at <StartupCode$fsyacc>.$FSharp.PowerPack.FsYacc.Driver.main@()
未处理的异常:系统。异常:给定了多个输入
位于FSharp.PowerPack.FsYacc.Driver。clo@67-5.调用(字符串x)
地址:$Arg.findMatchingArg$cont@104-1(FSharpRef`1游标,FSharpFunc`2其他,字符串usageText,FSharpList`1 argSpecs,字符串arg,单位变量)
价格为$Arg。findMatchingArg@64(FSharpRef`1游标,字符串[]argv,FSharpFunc`2其他,字符串usageText,Int32 nargs,FSharpList`1 argSpecs,字符串arg,FSharpList`1 args)
位于Internal.Utilities.ArgParser.ParsePartial(FSharpRef`1游标,字符串[]argv,IEnumerable`1参数,FSharpOption`1其他参数,FSharpOption`1 usageText)
位于Internal.Utilities.ArgParser.Parse(IEnumerable`1参数,FSharpOption`1其他参数,FSharpOption`1 usageText)
at.$FSharp.PowerPack.FsYacc.Driver.main@()

很抱歉耽搁了这么长时间,但最终还是解决了这个问题

无论是谁编写了FsYacc(F#team?)都错过了函数,这可以从他们自己在您链接的页面上的评论中看出。我尝试了几种变体,但这是我唯一能够实现的(注意:这需要一个
#nowarn“62“
.fsy
文件中的
,该文件将传播到
.fs
文件,或整个项目的
--nowarn:62
):

%{
开放式Ast
类型('a,'b)Fun='a->'b
%}
%启动startAst
%代币MyAst
%令牌EOF
%键入<(bool,MyAst)Fun>startAst
%%
startAst:
|MyAst EOF{(乐趣(x:bool)->
如果x那么
MyAst.Type1$1
其他的
MyAst.Type2)}

我不知道为什么(而且没有时间检查FsYacc的源代码,至少现在没有)。

如果您手动(通过命令行)运行
FsYacc.exe
,您将得到一个友好的错误。请这样做,并在这里发布。目前我只有“fsyacc.exe已停止工作”异常,没有任何日志信息。我确定我的代码不正确?但我不知道;我不知道如何正确地将它与FsYacc结合使用-可能有人会给我提供有用的链接(甚至是使用它的OCaml Yacc示例)@Vitaliy很乐意提供帮助。通过CodePlex报告(并验证问题确实存在于FsYacc源代码中):
%{

open Ast

type ('a,'b) Fun = 'a -> 'b

%}

%start startAst

%token <string> MyAst
%token EOF

%type < (bool, MyAst) Fun > startAst

%%

startAst:
| MyAst EOF { (fun (x : bool) ->
                if x then
                    MyAst.Type1 $1
                else
                    MyAst.Type2) }