Float and constructor syntax

This looks completely trivial, and I am no rookie, but it still surprises me:

$ ocaml
OCaml version 4.14.0
Enter #help;; for help.

# (Ok 5.0) ;;
- : (float, 'a) result = Ok 5.
# (Ok -5.0) ;;
Error: The constructor Ok expects 1 argument(s),
       but is applied here to 0 argument(s)
# (Ok (-5.0)) ;;
- : (float, 'a) result = Ok (-5.)
#

Looks like the “-” is parsed as an operator and not as part of the float literal, but doesn’t this violate the “longest first” lexing rule?


Ian

The unary operator - is always tokenized as an unary operator. Thus the flow of tokens emitted by the lexer for

Ok -5.0

is

UIDENT("Ok") MINUS FLOAT(5.0)

The really strange corner case is

let (~-)  x = x
let mystery =
  let x = 5.0 in
  -x + -5.0

(which is due to the fact that the parser recognizes the notion of signed constants)

1 Like
UIDENT("Ok") MINUS FLOAT(5.0)

Right, that is what I suspected.

the parser recognizes the notion of signed constants

The parser, and not the lexer?


Ian

I think you meant to use +. in there, yes?

Oho, this is interesting! So -x is not represented analogously to -5.0 : the first is the application of the operator “-” (or “-.”) to the expression x. The second is a signed constant. Interesting. Gotta remember this!

Yes, it is the parser that recognizes that MINUS constant is a signed constant: ocaml/parser.mly at trunk · ocaml/ocaml · GitHub .

1 Like