Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

119 lines (95 sloc) 3.711 kb
\section{Scanner and Parser for Annotations}
% ------------------------------------------------------------------
\subsection{Parser}
% ------------------------------------------------------------------
<<parser.mly>>=
%{
module A = Annot.ByPosition
exception Error of string
let error fmt = Printf.kprintf (fun msg -> raise (Error msg)) fmt
let (@@) f x = f x
%}
<<types>>
%%
<<grammar>>
@
<<types>>=
%start annotations
%type <Annot.t> annotations
%token EOF
%token <string> STRING
%token <int> INT
%token <string> ANNOT IDENT CALL
@
<<grammar>>=
annotations : annotations annot { let interval, annots = $2 in
List.fold_right (A.add interval) annots $1
}
| /**/ { A.empty }
annot : location location data { ($1,$2), $3 }
data : ANNOT data { $1 :: $2 }
| ANNOT { [$1] }
| IDENT data { $2 }
| IDENT { [] }
| CALL data { $2 }
| CALL { [] }
;
location : STRING INT INT INT { $2, $4-$3 }
@
% ------------------------------------------------------------------
\subsection{Scanner}
% ------------------------------------------------------------------
The scanner splits the input into tokens. Tokens are defined by the
parser (in [[parser.mli]]).
<<scanner.mli>>=
val token: Lexing.lexbuf -> Parser.token
<<scanner.mll>>=
{
module P = Parser (* tokens are defined here *)
let get = Lexing.lexeme
let getchar = Lexing.lexeme_char
let strlen = String.length
let pos_start = Lexing.lexeme_start
let pos_end = Lexing.lexeme_end
exception Error of string
let error fmt = Printf.kprintf (fun msg -> raise (Error msg)) fmt
let (@@) f x = f x
}
@
<<scanner.mll>>=
let digit = ['0'-'9']
let ws = [' ' '\t' '\r']
let nl = '\n'
@
<<scanner.mll>>=
rule token = parse
eof { P.EOF }
| ws+ { token lexbuf }
| nl { token lexbuf }
| digit+ { P.INT(int_of_string (get lexbuf)) }
| '"' ([^'"']+ as str) '"'{ P.STRING (str)}
| "type(\n" { annot `Type (Buffer.create 80) lexbuf }
| "ident(\n" { annot `Ident (Buffer.create 80) lexbuf }
| "call(\n" { annot `Call (Buffer.create 80) lexbuf }
| _ { let str = String.escaped @@ get lexbuf in
let off = Lexing.lexeme_start lexbuf in
error "illegal character: '%s' at offset %d" str off
}
and annot mode buffer = parse
eof { error "unexpected end of file" }
| [^ '\n']+ { Buffer.add_string buffer (get lexbuf)
; annot mode buffer lexbuf
}
| nl { Buffer.add_string buffer (get lexbuf)
; annot mode buffer lexbuf
}
| nl ')' { match mode with
|`Type -> P.ANNOT(Buffer.contents buffer)
|`Ident -> P.IDENT(Buffer.contents buffer)
|`Call -> P.CALL(Buffer.contents buffer)
}
| _ { let str = String.escaped @@ get lexbuf in
let off = Lexing.lexeme_start lexbuf in
error "illegal character: '%s' at offset %d" str off
}
@
Jump to Line
Something went wrong with that request. Please try again.