(* Title: Pure/Isar/antiquote.ML ID: $Id: antiquote.ML,v 1.5 2004/06/21 08:26:11 kleing Exp $ Author: Markus Wenzel, TU Muenchen Text with antiquotations of inner items (terms, types etc.). *) signature ANTIQUOTE = sig exception ANTIQUOTE_FAIL of (string * Position.T) * exn datatype antiquote = Text of string | Antiq of string * Position.T val is_antiq: antiquote -> bool val antiquotes_of: string * Position.T -> antiquote list end; structure Antiquote: ANTIQUOTE = struct (* datatype antiquote *) exception ANTIQUOTE_FAIL of (string * Position.T) * exn; datatype antiquote = Text of string | Antiq of string * Position.T; fun is_antiq (Text _) = false | is_antiq (Antiq _) = true; (* scan_antiquote *) local structure T = OuterLex; val scan_txt = T.scan_blank || T.keep_line ($$ "@" --| Scan.ahead (Scan.one (not_equal "{"))) || T.keep_line (Scan.one (not_equal "@" andf Symbol.not_sync andf Symbol.not_eof)); fun escape "\\" = "\\\\" | escape "\"" = "\\\"" | escape s = s; val quote_escape = Library.quote o implode o map escape o Symbol.explode; val scan_ant = T.scan_blank || T.scan_string >> quote_escape || T.keep_line (Scan.one (not_equal "}" andf Symbol.not_sync andf Symbol.not_eof)); val scan_antiq = T.keep_line ($$ "@" -- $$ "{") |-- T.!!! "missing closing brace of antiquotation" (Scan.repeat scan_ant >> implode) --| T.keep_line ($$ "}"); in fun scan_antiquote (pos, ss) = (pos, ss) |> (Scan.repeat1 scan_txt >> (Text o implode) || scan_antiq >> (fn s => Antiq (s, pos))); end; (* antiquotes_of *) fun antiquotes_of (s, pos) = (case Scan.error (Scan.finite' Symbol.stopper (Scan.repeat scan_antiquote)) (pos, Symbol.explode s) of (xs, (_, [])) => xs | (_, (pos', ss)) => error ("Malformed quotation/antiquotation text at: " ^ quote (Symbol.beginning 10 ss) ^ Position.str_of pos')); end;