我正在编写一个简单的解析器函数,它需要一个流中的项目,并返回一个 int,但由于某种原因,编译器出于我无法理解的原因一直期待一个浮点数;特别是考虑到代码实际上是来自 llvm ocaml 教程的示例代码。
我已经尝试将这两个变量类型转换为整数,并且通常只是摆弄语法,但是该函数非常简单,我无法弄清楚实际出了什么问题。我知道对于普通函数,可以指定类型, let: type->type
但我不知道这将如何与解析器函数一起使用。
这是功能:
let parse_binary_precedence = parser
| [< 'Token.Number n >] -> int_of_float n
| [< >] -> 30
in
这是在也是问题一部分的情况下使用它的更大背景(尽管我不认为它是):
let parse_binary_precedence = parser
| [< 'Token.Number n >] -> (int_of_float n)
| [< >] -> 30
in
parser
| [< (prefix, kind)=parse_operator;
'Token.Kwd op ?? "expected operator";
prec = parse_binary_precedence;
'Token.Kwd '(' ?? "expected '(' in operator prototype";
args = parse_first_arg [];
'Token.Kwd ')' ?? "expected ')' in operator protoype" >] ->
我目前只是获得标准
File "parser.ml", line 108, characters 49-50:
Error: This expression has type int but an expression was expected of type
float
类型错误。
有谁知道为什么这期待浮动?如何使函数期望一个 int?
编辑:
我现在意识到我现在措辞很糟糕,但是我意识到程序的上下文决定了函数的类型,我在问程序中的什么让它假设函数返回一个 int。似乎它超出了我发布的范围,因此我正在使用与显示的所有内容相关的代码更新我的帖子。
这是相关代码的完整集。很抱歉一开始就没有包括这个。
令牌.ml:
type token =
(*primary*)
| Ident of string | Number of int
(*control*)
| If | Else | For
(*user ops*)
| Binary | Unary
解析器.ml
let parse_prototype =
let rec parse_args accumulator = parser
| [< 'Token.Kwd ','; 'Token.Ident id; e=parse_args (id :: accumulator) >] -> e
| [< >] -> accumulator
in
let parse_first_arg accumulator = parser
| [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
| [< >] -> accumulator
in
let parse_operator = parser
| [< 'Token.Binary >] -> "binary", 2
| [< 'Token.Unary >] -> "unary", 1
in
let parse_binary_precedence = parser
| [< 'Token.Number n >] -> (int_of_float n) (*line 108*)
| [< >] -> 30
in
parser
| [< 'Token.Ident id;
'Token.Kwd '(' ?? "expected '(' in prototype";
args= parse_first_arg [];
'Token.Kwd ')' ?? "expected closing ')' in prototype " >] ->
Ast.Prototype (id, Array.of_list (List.rev args))
| [< (prefix, kind)=parse_operator;
'Token.Kwd op ?? "expected operator";
prec = parse_binary_precedence;
'Token.Kwd '(' ?? "expected '(' in operator prototype";
args = parse_first_arg [];
'Token.Kwd ')' ?? "expected ')' in operator protoype" >] ->
let name = prefix ^ (String.make 1 op) in
let args = Array.of_list (List.rev args) in
(*verify right number of args for op*)
if Array.length args != kind then
raise (Stream.Error "invalid number of operands in op def")
else
if kind == 1 then
Ast.Prototype (name, args)
else
Ast.BinOpPrototype (name, args, prec)
| [< >] ->
raise (Stream.Error "expected func name in prototype")
astml
type proto =
| Prototype of string * string array
| BinOpPrototype of string * string array * int