Lexical syntax for Isabelle/ML and Standard ML.
*)
signature ML_LEX = sig val keywords: stringlist datatype token_kind =
Keyword | Ident | Long_Ident | Type_Var | Word | Int | Real | Char | String |
Space | Comment of Comment.kind option | Error ofstring | EOF
eqtype token val stopper: token Scan.stopper val is_ident_with: (string -> bool) -> token -> bool val is_regular: token -> bool val is_improper: token -> bool val is_comment: token -> bool val set_range: Position.range -> token -> token val range_of: token -> Position.range val pos_of: token -> Position.T val end_pos_of: token -> Position.T val kind_of: token -> token_kind val content_of: token -> string val check_content_of: token -> string val flatten: token list -> string val source: (Symbol.symbol, 'a) Source.source ->
(token, (Symbol_Pos.T, Position.T * (Symbol.symbol, 'a) Source.source)
Source.source) Source.source val tokenize: string -> token list val tokenize_range: Position.range -> string -> token list val tokenize_no_range: string -> token list val read_text: Symbol_Pos.text * Position.T -> token Antiquote.antiquote list val read: Symbol_Pos.text -> token Antiquote.antiquote list val read_range: Position.range -> Symbol_Pos.text -> token Antiquote.antiquote list val read_source': {language: bool -> Markup.T, opaque_warning: bool, symbols: bool} ->
token Antiquote.antiquote Symbol_Pos.scanner -> Input.source -> token Antiquote.antiquote list val read_source: Input.source -> token Antiquote.antiquote list val read_source_sml: Input.source -> token Antiquote.antiquote list val read_symbols: Symbol_Pos.T list -> token Antiquote.antiquote list val read_symbols_sml: Symbol_Pos.T list -> token Antiquote.antiquote list end;
fun warning_opaque tok =
(case tok of
Token (_, (Keyword, ":>")) =>
warning ("Opaque signature matching (:>) fails to work with ML pretty printing --\n\
\prefer non-opaque matching (:) possibly with abstype" ^
Position.here (pos_of tok))
| _ => ());
fun check_content_of tok =
(case kind_of tok of
Error msg => error msg
| _ => content_of tok);
(* flatten *)
fun flatten_content (tok :: (toks as tok' :: _)) =
Symbol.escape (check_content_of tok) ::
(if is_improper tok orelse is_improper tok' then flatten_content toks else Symbol.space :: flatten_content toks)
| flatten_content toks = map (Symbol.escape o check_content_of) toks;
fun token_report (tok as Token ((pos, _), (kind, x))) = let val (markup, txt) = ifnot (is_keyword tok) then token_kind_markup kind elseif is_delimiter tok then (Markup.ML_delimiter, "") elseif Symset.member keywords2 x then (Markup.ML_keyword2 |> Markup.keyword_properties, "") elseif Symset.member keywords3 x then (Markup.ML_keyword3 |> Markup.keyword_properties, "") else (Markup.ML_keyword1 |> Markup.keyword_properties, ""); in ((pos, markup), txt) end;
fun recover msg =
(recover_char ||
recover_string ||
Symbol_Pos.recover_cartouche ||
Symbol_Pos.recover_comment ||
Scan.one (Symbol.not_eof o Symbol_Pos.symbol) >> single)
>> (single o token (Error msg));
fun reader {opaque_warning} scan syms = let val termination = if null syms then [] else let val pos1 = List.last syms |-> Position.symbol; val pos2 = Position.symbol Symbol.space pos1; in [Antiquote.Text (Token (Position.range (pos1, pos2), (Space, Symbol.space)))] end;
fun check (Antiquote.Text tok) =
(check_content_of tok; if opaque_warning then warning_opaque tok else ())
| check _ = (); val input =
Source.of_list syms
|> Source.source Symbol_Pos.stopper
(Scan.recover (Scan.bulk (!!! "bad input" scan))
(fn msg => recover msg >> map Antiquote.Text))
|> Source.exhaust; val _ = Position.reports (Antiquote.antiq_reports input); val _ = Position.reports_text (maps (fn Antiquote.Text t => [token_report t] | _ => []) input); val _ = List.app check input; in input @ termination end;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.