58 lines
1.6 KiB
Plaintext
58 lines
1.6 KiB
Plaintext
{
|
|
module Lexer
|
|
|
|
open System
|
|
open FSharp.Text.Lexing
|
|
open System.Text
|
|
|
|
let keyword (s : string) =
|
|
match s with
|
|
| "let" -> Parser.LET
|
|
| "in" -> Parser.IN
|
|
| "sum" -> Parser.SUM
|
|
| "prod" -> Parser.PROD
|
|
| "max" -> Parser.MAX
|
|
| "argmax" -> Parser.ARGMAX
|
|
| "to" -> Parser.TO
|
|
| "of" -> Parser.OF
|
|
| _ -> Parser.VAR s
|
|
}
|
|
|
|
rule Token = parse
|
|
(* Skip whitespace. *)
|
|
[' ' '\t' '\r' '\n' ]+
|
|
{ Token lexbuf }
|
|
|
|
(* Integers. *)
|
|
| '0' | ['1'-'9']['0'-'9']*
|
|
{ Parser.INT (int (Encoding.UTF8.GetString lexbuf.Lexeme)) }
|
|
|
|
(* Symbols *)
|
|
| '(' { Parser.LPAR }
|
|
| ')' { Parser.RPAR }
|
|
| '=' { Parser.EQ }
|
|
| '+' { Parser.PLUS }
|
|
| '-' { Parser.MINUS }
|
|
| '*' { Parser.TIMES }
|
|
|
|
| ['a'-'z' 'A'-'Z'] (['a'-'z' 'A'-'Z' '_']|'_'['0'-'9'])*
|
|
{ keyword (Encoding.UTF8.GetString lexbuf.Lexeme) }
|
|
|
|
(* FIXME: You should implement lexing for:
|
|
(1) Variable names: may contain letters, digits and underscores,
|
|
but it must start with one (or several) letters,
|
|
and a digit must be preceeded by an underscore.
|
|
(2) Keywords: 'let', 'in', 'sum', ...
|
|
(3) Symbols: '=', '+', ...
|
|
For (1) and (2), please change the regular expression above
|
|
to be consistent with the rule defining variable names,
|
|
and implement the keywords function.
|
|
For (3), add the relevant regular expressions under 'Symbols'
|
|
*)
|
|
|
|
(* Special end of file symbol. *)
|
|
| eof { Parser.EOF }
|
|
|
|
(* We don't understand anything else. *)
|
|
| _ { failwith "lexer error" }
|