csharpfftfsharpintegrationinterpolationlinear-algebramathdifferentiationmatrixnumericsrandomregressionstatisticsmathnet
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
6.8 KiB
202 lines
6.8 KiB
{
|
|
(* (c) Microsoft Corporation 2005-2008. *)
|
|
|
|
open Fslexast
|
|
open Fslexpars
|
|
open Internal.Utilities
|
|
open Internal.Utilities.Text.Lexing
|
|
open System.Text
|
|
|
|
let escape c =
|
|
match c with
|
|
| '\\' -> '\\'
|
|
| '\'' -> '\''
|
|
| 'n' -> '\n'
|
|
| 't' -> '\t'
|
|
| 'b' -> '\b'
|
|
| 'r' -> '\r'
|
|
| c -> c
|
|
|
|
let lexeme (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
|
|
let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
|
|
|
|
let unexpected_char lexbuf =
|
|
failwith ("Unexpected character '"^(lexeme lexbuf)^"'")
|
|
|
|
let digit d =
|
|
if d >= '0' && d <= '9' then int32 d - int32 '0'
|
|
else failwith "digit"
|
|
|
|
let hexdigit d =
|
|
if d >= '0' && d <= '9' then digit d
|
|
else if d >= 'a' && d <= 'f' then int32 d - int32 'a' + 10
|
|
else if d >= 'A' && d <= 'F' then int32 d - int32 'A' + 10
|
|
else failwithf "bad hexdigit: %c" d
|
|
|
|
let trigraph c1 c2 c3 =
|
|
char (digit c1 * 100 + digit c2 * 10 + digit c3)
|
|
|
|
let hexgraph c1 c2 =
|
|
char (hexdigit c1 * 16 + hexdigit c2)
|
|
|
|
let unicodegraph_short (s:string) =
|
|
if s.Length <> 4 then failwith "unicodegraph";
|
|
char(hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3])
|
|
|
|
let unicodegraph_long (s:string) =
|
|
if s.Length <> 8 then failwith "unicodegraph_long";
|
|
let high = hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3] in
|
|
let low = hexdigit s.[4] * 4096 + hexdigit s.[5] * 256 + hexdigit s.[6] * 16 + hexdigit s.[7] in
|
|
if high = 0 then None, char low
|
|
else
|
|
(* A surrogate pair - see http://www.unicode.org/unicode/uni2book/ch03.pdf, section 3.7 *)
|
|
Some (char(0xD800 + ((high * 0x10000 + low - 0x10000) / 0x400))),
|
|
char(0xDF30 + ((high * 0x10000 + low - 0x10000) % 0x400))
|
|
|
|
}
|
|
|
|
let letter = ['A'-'Z'] | ['a'-'z']
|
|
let digit = ['0'-'9']
|
|
let whitespace = [' ' '\t']
|
|
let char = '\'' ( [^'\\'] | ('\\' ( '\\' | '\'' | "\"" | 'n' | 't' | 'b' | 'r'))) '\''
|
|
let hex = ['0'-'9'] | ['A'-'F'] | ['a'-'f']
|
|
let hexgraph = '\\' 'x' hex hex
|
|
let trigraph = '\\' digit digit digit
|
|
let newline = ('\n' | '\r' '\n')
|
|
let ident_start_char = letter
|
|
let ident_char = ( ident_start_char| digit | ['\'' '_'] )
|
|
let ident = ident_start_char ident_char*
|
|
|
|
let unicodegraph_short = '\\' 'u' hex hex hex hex
|
|
let unicodegraph_long = '\\' 'U' hex hex hex hex hex hex hex hex
|
|
|
|
rule token = parse
|
|
| "rule" {RULE }
|
|
| "parse" {PARSE }
|
|
| "eof" {EOF }
|
|
| "let" {LET }
|
|
| "and" {AND }
|
|
| char
|
|
{ let s = lexeme lexbuf in
|
|
CHAR (if s.[1] = '\\' then escape s.[2] else s.[1]) }
|
|
|
|
| '\'' trigraph '\''
|
|
{ let s = lexeme lexbuf in
|
|
CHAR (trigraph s.[2] s.[3] s.[4]) }
|
|
|
|
| '\'' hexgraph '\''
|
|
{ let s = lexeme lexbuf in
|
|
CHAR (hexgraph s.[3] s.[4]) }
|
|
|
|
| '\'' unicodegraph_short '\''
|
|
{ let s = lexeme lexbuf in
|
|
CHAR (unicodegraph_short s.[3..6]) }
|
|
|
|
| '\'' unicodegraph_long '\''
|
|
{ let s = lexeme lexbuf in
|
|
match (unicodegraph_long s.[3..10]) with
|
|
| None, c -> CHAR(c)
|
|
| Some _ , _ -> failwith "Unicode characters needing surrogate pairs are not yet supported by this tool" }
|
|
|
|
| '\'' '\\' ['A'-'Z'] ['a'-'z'] '\''
|
|
{ let s = (lexeme lexbuf).[2..3] in
|
|
UNICODE_CATEGORY (s) }
|
|
|
|
| '{' { let p = lexbuf.StartPos in code p (new StringBuilder 100) lexbuf }
|
|
|
|
| '"' { string lexbuf.StartPos (new StringBuilder 100) lexbuf }
|
|
|
|
| whitespace+ { token lexbuf }
|
|
| newline { newline lexbuf; token lexbuf }
|
|
| ident_start_char ident_char* { IDENT (lexeme lexbuf) }
|
|
| '|' { BAR }
|
|
| '.' { DOT }
|
|
| '+' { PLUS }
|
|
| '*' { STAR }
|
|
| '?' { QMARK }
|
|
| '=' { EQUALS }
|
|
| '[' { LBRACK }
|
|
| ']' { RBRACK }
|
|
| '(' { LPAREN }
|
|
| ')' { RPAREN }
|
|
| '_' { UNDERSCORE }
|
|
| '^' { HAT }
|
|
| '-' { DASH }
|
|
| "(*" { ignore(comment lexbuf.StartPos lexbuf); token lexbuf }
|
|
| "//" [^'\n''\r']* { token lexbuf }
|
|
| _ { unexpected_char lexbuf }
|
|
| eof { EOF }
|
|
and string p buff = parse
|
|
| '\\' newline { newline lexbuf; string p buff lexbuf }
|
|
| '\\' ( '"' | '\\' | '\'' | 'n' | 't' | 'b' | 'r')
|
|
{ let _ = buff.Append (escape (lexeme lexbuf).[1]) in
|
|
string p buff lexbuf }
|
|
| trigraph
|
|
{ let s = lexeme lexbuf in
|
|
let _ = buff.Append (trigraph s.[1] s.[2] s.[3]) in
|
|
string p buff lexbuf }
|
|
| '"' { STRING (buff.ToString()) }
|
|
| newline { newline lexbuf;
|
|
let _ = buff.Append System.Environment.NewLine in
|
|
string p buff lexbuf }
|
|
| (whitespace | letter | digit) +
|
|
{ let _ = buff.Append (lexeme lexbuf) in
|
|
string p buff lexbuf }
|
|
| eof { failwith (Printf.sprintf "end of file in string started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol)) }
|
|
| _ { let _ = buff.Append (lexeme lexbuf).[0] in
|
|
string p buff lexbuf }
|
|
and code p buff = parse
|
|
| "}" { CODE (buff.ToString(), p) }
|
|
| "{" { let _ = buff.Append (lexeme lexbuf) in
|
|
ignore(code p buff lexbuf);
|
|
let _ = buff.Append "}" in
|
|
code p buff lexbuf }
|
|
| '\\' ('"' | '\\')
|
|
{ let _ = buff.Append (lexeme lexbuf) in
|
|
code p buff lexbuf }
|
|
| "\"" { let _ = buff.Append (lexeme lexbuf) in
|
|
ignore(codestring buff lexbuf);
|
|
code p buff lexbuf }
|
|
| newline { newline lexbuf;
|
|
let _ = buff.Append System.Environment.NewLine in
|
|
code p buff lexbuf }
|
|
| (whitespace | letter | digit) +
|
|
{ let _ = buff.Append (lexeme lexbuf) in
|
|
code p buff lexbuf }
|
|
| "//" [^'\n''\r']*
|
|
{ let _ = buff.Append (lexeme lexbuf) in
|
|
code p buff lexbuf }
|
|
| eof { EOF }
|
|
| _ { let _ = buff.Append (lexeme lexbuf).[0] in
|
|
code p buff lexbuf }
|
|
|
|
and codestring buff = parse
|
|
| '\\' ('"' | '\\')
|
|
{ let _ = buff.Append (lexeme lexbuf) in
|
|
codestring buff lexbuf }
|
|
| '"' { let _ = buff.Append (lexeme lexbuf) in
|
|
buff.ToString() }
|
|
| newline { newline lexbuf;
|
|
let _ = buff.Append System.Environment.NewLine in
|
|
codestring buff lexbuf }
|
|
| (whitespace | letter | digit) +
|
|
{ let _ = buff.Append (lexeme lexbuf) in
|
|
codestring buff lexbuf }
|
|
| eof { failwith "unterminated string in code" }
|
|
| _ { let _ = buff.Append (lexeme lexbuf).[0] in
|
|
codestring buff lexbuf }
|
|
|
|
and comment p = parse
|
|
| char { comment p lexbuf }
|
|
| '"' { ignore(try string lexbuf.StartPos (new StringBuilder 100) lexbuf
|
|
with Failure s -> failwith (s ^ "\n" ^ Printf.sprintf "error while processing string nested in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol)));
|
|
comment p lexbuf }
|
|
| "(*" { ignore(try comment p lexbuf with Failure s -> failwith (s ^ "\n" ^ Printf.sprintf "error while processing nested comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol)));
|
|
comment p lexbuf }
|
|
| newline { newline lexbuf; comment p lexbuf }
|
|
| "*)" { () }
|
|
| eof { failwith (Printf.sprintf "end of file in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol)) }
|
|
| [^ '\'' '(' '*' '\n' '\r' '"' ')' ]+ { comment p lexbuf }
|
|
| _ { comment p lexbuf }
|
|
|
|
|
|
|