Commit 7466ea22 authored by Pietro Abate's avatar Pietro Abate
Browse files

[r2003-09-23 19:41:35 by cvscast] Constantes structurees + suite nettoyage

Original author: cvscast
Date: 2003-09-23 19:41:36+00:00
parent 2b3c3aab
0.2.0 0.2.0
* Rewriting to use ocaml 3.07 * Code upgraded to Ocaml 3.07+beta2
* Major cleaning in progress
* Using ulex instead of wlex
* Allow structured constants in default value patterns (p := c)
0.1.1 0.1.1
* Various bug fixes (expat might now work) * Various bug fixes (expat might now work)
......
include Makefile.distrib NATIVE=false
# We put this rule here to avoid re-building wlexer.ml on include Makefile.distrib
# user installation (wlex may not be available)
#parser/wlexer.ml: parser/wlexer.mll
# wlex parser/wlexer.mll
# For development # For development
pull: tools/pull.$(EXTENSION) pull: tools/pull.$(EXTENSION)
$(LINK) -o $@ $^ $(LINK) -o $@ $^
PREPRO = $(SYNTAX) pr_o.cmo PREPRO = camlp4o -I `ocamlfind query ulex` pa_ulex.cma pr_o.cmo $(SYNTAX) -sep "\n"
profile: profile: misc/q_symbol.cmo
rm -Rf prepro rm -Rf prepro
mkdir prepro mkdir prepro
for i in $(DIRS); do \ for i in $(DIRS); do \
...@@ -26,9 +21,11 @@ profile: ...@@ -26,9 +21,11 @@ profile:
fi; \ fi; \
done; \ done; \
done done
#cp parser/wlexer.mll prepro/parser/ cp Makefile.distrib Makefile Makefile.conf prepro/
cp Makefile depend prepro/ (cd prepro; \
(cd prepro; $(MAKE) cduce PROFILE=true SYNTAX_PARSER= NATIVE=false) touch depend; \
$(MAKE) compute_depend PROFILE=true SYNTAX_PARSER= ; \
$(MAKE) cduce PROFILE=true SYNTAX_PARSER= NATIVE=false)
# Site-specific installation # Site-specific installation
......
# build CDuce using OCaml native code compiler # build CDuce using OCaml native code compiler
NATIVE = true ifeq ($(NATIVE), false)
else
NATIVE = true
endif
# profiling support # profiling support
PROFILE = false PROFILE = false
......
include Makefile.conf include Makefile.conf
VERSION = 0.2.0 VERSION = 0.1.2
PACKAGES = pxp-engine pxp-lex-iso88591 ulex camlp4 num cgi pcre netstring PACKAGES = pxp-engine pxp-lex-iso88591 ulex camlp4 num cgi pcre netstring
ifeq ($(PXP_WLEX), true) ifeq ($(PXP_WLEX), true)
...@@ -8,10 +8,7 @@ else ...@@ -8,10 +8,7 @@ else
PACKAGES += pxp-lex-utf8 PACKAGES += pxp-lex-utf8
endif endif
ULEX_PATH = `ocamlfind query ulex` SYNTAX = -I misc/ pa_extend.cmo q_symbol.cmo \
SYNTAX = camlp4o -I misc/ pa_extend.cmo \
q_symbol.cmo \
$(shell ocamlfind query ulex)/pa_ulex.cma \
-symbol cduce_version=\"$(VERSION)\" \ -symbol cduce_version=\"$(VERSION)\" \
-symbol build_date=\"$(shell date +%Y-%m-%d)\" \ -symbol build_date=\"$(shell date +%Y-%m-%d)\" \
-symbol session_dir=\"$(SESSION_DIR)\" -symbol session_dir=\"$(SESSION_DIR)\"
...@@ -27,14 +24,16 @@ ifeq ($(EXPAT), true) ...@@ -27,14 +24,16 @@ ifeq ($(EXPAT), true)
SYNTAX += -symbol EXPAT= SYNTAX += -symbol EXPAT=
endif endif
SYNTAX_PARSER = -pp '$(SYNTAX)' SYNTAX_PARSER = -syntax camlp4o $(SYNTAX:%=-ppopt %)
CAMLC_P = ocamlc CAMLC_P = ocamlc
DEPEND_OCAMLDEP = misc/q_symbol.cmo
ifeq ($(PROFILE), true) ifeq ($(PROFILE), true)
CAMLOPT_P = ocamlopt -p CAMLOPT_P = ocamlopt -p
ifeq ($(NATIVE), false) ifeq ($(NATIVE), false)
CAMLC_P = ocamlcp -p a CAMLC_P = ocamlcp -p a
SYNTAX_PARSER = SYNTAX_PARSER =
DEPEND_OCAMLDEP =
endif endif
else else
CAMLOPT_P = ocamlopt -inline 25 CAMLOPT_P = ocamlopt -inline 25
...@@ -67,7 +66,7 @@ uninstall: ...@@ -67,7 +66,7 @@ uninstall:
# Source directories # Source directories
DIRS = misc parser schema typing types runtime driver DIRS = misc parser schema typing types runtime driver module
CLEAN_DIRS = $(DIRS) tools tests CLEAN_DIRS = $(DIRS) tools tests
# Objects to build # Objects to build
...@@ -124,14 +123,11 @@ validate: $(OBJECTS:.cmo=.$(EXTENSION)) tools/validate.ml ...@@ -124,14 +123,11 @@ validate: $(OBJECTS:.cmo=.$(EXTENSION)) tools/validate.ml
$(LINK) $(INCLUDES) -o $@ $^ $(LINK) $(INCLUDES) -o $@ $^
.PHONY: compute_depend .PHONY: compute_depend
compute_depend: misc/q_symbol.cmo compute_depend: $(DEPEND_OCAMLDEP)
@echo "Computing dependencies ..." @echo "Computing dependencies ..."
ocamldep $(INCLUDES) $(SYNTAX_PARSER) $(DEPEND) | \ ocamlfind ocamldep -package "$(PACKAGES)" $(INCLUDES) $(SYNTAX_PARSER) $(DEPEND) | \
sed -e "s|: |: misc/q_symbol.cmo |" > depend sed -e "s|: |: misc/q_symbol.cmo |" > depend
#parser/wlexer.ml: parser/wlexer.mll
# wlex parser/wlexer.mll
clean: clean:
for i in $(CLEAN_DIRS); do \ for i in $(CLEAN_DIRS); do \
(cd $$i; rm -f *.cmi *.cmo *.cma *.cmx *.o *~); \ (cd $$i; rm -f *.cmi *.cmo *.cma *.cmx *.o *~); \
...@@ -151,7 +147,7 @@ misc/q_symbol.cmo: misc/q_symbol.ml ...@@ -151,7 +147,7 @@ misc/q_symbol.cmo: misc/q_symbol.ml
$(CAMLC) -c -pp 'camlp4o pa_extend.cmo q_MLast.cmo' $< $(CAMLC) -c -pp 'camlp4o pa_extend.cmo q_MLast.cmo' $<
.ml.cmo: .ml.cmo:
$(CAMLC) -c $(SYNTAX_PARSER) $(INCLUDES) $< $(CAMLC) -c $(INCLUDES) $(SYNTAX_PARSER) $<
.ml.cmx: .ml.cmx:
$(CAMLOPT) -c $(SYNTAX_PARSER) $(INCLUDES) $< $(CAMLOPT) -c $(SYNTAX_PARSER) $(INCLUDES) $<
......
...@@ -57,7 +57,7 @@ Beppe 2003-03-02 ...@@ -57,7 +57,7 @@ Beppe 2003-03-02
Add an operator random(n) Add an operator random(n)
é
====================================================================== ======================================================================
...@@ -147,6 +147,9 @@ Alain 2003-06-17 ...@@ -147,6 +147,9 @@ Alain 2003-06-17
Unicode dans un source CDuce en Latin1 Unicode dans un source CDuce en Latin1
- source en UTF8 (ou autre) - source en UTF8 (ou autre)
Alain 2003-09-23
Avec le passage à ulex, on gagne la possibilité de changer
l'encoding du source
====================================================================== ======================================================================
...@@ -159,6 +162,9 @@ Alain 2003-05-15 ...@@ -159,6 +162,9 @@ Alain 2003-05-15
Etudier les problèmes avec print_xml (ex: XHTML a besoin Etudier les problèmes avec print_xml (ex: XHTML a besoin
d'avoir un prefixe bien défini...) d'avoir un prefixe bien défini...)
Alain 2003-09-23
Fait il y a longtemps.
====================================================================== ======================================================================
Alain 2003-05-19 Alain 2003-05-19
......
...@@ -90,10 +90,10 @@ parser/location.cmo: misc/q_symbol.cmo parser/location.cmi ...@@ -90,10 +90,10 @@ parser/location.cmo: misc/q_symbol.cmo parser/location.cmi
parser/location.cmx: misc/q_symbol.cmo parser/location.cmi parser/location.cmx: misc/q_symbol.cmo parser/location.cmi
parser/ulexer.cmo: misc/q_symbol.cmo parser/ulexer.cmi parser/ulexer.cmo: misc/q_symbol.cmo parser/ulexer.cmi
parser/ulexer.cmx: misc/q_symbol.cmo parser/ulexer.cmi parser/ulexer.cmx: misc/q_symbol.cmo parser/ulexer.cmi
parser/ast.cmo: misc/q_symbol.cmo types/ident.cmo parser/location.cmi misc/ns.cmi \ parser/ast.cmo: misc/q_symbol.cmo types/chars.cmi types/ident.cmo types/intervals.cmi \
schema/schema_types.cmi types/types.cmi parser/location.cmi misc/ns.cmi schema/schema_types.cmi types/types.cmi
parser/ast.cmx: misc/q_symbol.cmo types/ident.cmx parser/location.cmx misc/ns.cmx \ parser/ast.cmx: misc/q_symbol.cmo types/chars.cmx types/ident.cmx types/intervals.cmx \
schema/schema_types.cmx types/types.cmx parser/location.cmx misc/ns.cmx schema/schema_types.cmx types/types.cmx
parser/parser.cmo: misc/q_symbol.cmo parser/ast.cmo types/atoms.cmi types/chars.cmi \ parser/parser.cmo: misc/q_symbol.cmo parser/ast.cmo types/atoms.cmi types/chars.cmi \
misc/encodings.cmi types/ident.cmo types/intervals.cmi \ misc/encodings.cmi types/ident.cmo types/intervals.cmi \
parser/location.cmi misc/ns.cmi schema/schema_parser.cmi \ parser/location.cmi misc/ns.cmi schema/schema_parser.cmi \
......
...@@ -120,14 +120,6 @@ let do_file s = ...@@ -120,14 +120,6 @@ let do_file s =
let chan = open_in s in let chan = open_in s in
Location.push_source (`File s); Location.push_source (`File s);
let input = Stream.of_channel chan in let input = Stream.of_channel chan in
if Stream.npeek 2 input = ['#';'!'] then
(
let rec count n =
match Stream.next input with
| '\n' -> n
| _ -> count (n + 1) in
Ulexer.set_delta_loc (count 1)
);
let ok = Cduce.script ppf ppf_err input in let ok = Cduce.script ppf ppf_err input in
close_in chan; close_in chan;
if not ok then exit 1 if not ok then exit 1
......
...@@ -9,6 +9,7 @@ struct ...@@ -9,6 +9,7 @@ struct
let equal (x : t) y = x = y let equal (x : t) y = x = y
let compare (x : t) y = compare x y let compare (x : t) y = compare x y
(* TODO: handle UTF-8 viewport *) (* TODO: handle UTF-8 viewport *)
let to_string s = let to_string s =
Netconversion.recode_string Netconversion.recode_string
......
...@@ -31,10 +31,6 @@ and toplevel_directive = ...@@ -31,10 +31,6 @@ and toplevel_directive =
] ]
and pconst =
| Const_internal of Types.const
| Const_atom of U.t
and pexpr = and pexpr =
| LocatedExpr of loc * pexpr | LocatedExpr of loc * pexpr
...@@ -44,8 +40,10 @@ and pexpr = ...@@ -44,8 +40,10 @@ and pexpr =
| Abstraction of abstr | Abstraction of abstr
(* Data constructors *) (* Data constructors *)
| Cst of pconst | Integer of Intervals.V.t
| Char of Chars.V.t
| Pair of pexpr * pexpr | Pair of pexpr * pexpr
| Atom of U.t
| Xml of pexpr * pexpr | Xml of pexpr * pexpr
| RecordLitt of (label * pexpr) list | RecordLitt of (label * pexpr) list
| String of U.uindex * U.uindex * U.t * pexpr | String of U.uindex * U.uindex * U.t * pexpr
...@@ -87,7 +85,7 @@ and ppat' = ...@@ -87,7 +85,7 @@ and ppat' =
| PatVar of U.t | PatVar of U.t
| SchemaVar of (* type/pattern schema variable *) | SchemaVar of (* type/pattern schema variable *)
schema_item_kind * string * string schema_item_kind * string * string
| AtomT of U.t | Cst of pexpr
| NsT of U.t | NsT of U.t
| Recurs of ppat * (U.t * ppat) list | Recurs of ppat * (U.t * ppat) list
| Internal of Types.descr | Internal of Types.descr
...@@ -99,7 +97,7 @@ and ppat' = ...@@ -99,7 +97,7 @@ and ppat' =
| Arrow of ppat * ppat | Arrow of ppat * ppat
| Optional of ppat | Optional of ppat
| Record of bool * (label * ppat) list | Record of bool * (label * ppat) list
| Constant of id * pconst | Constant of id * pexpr
| Regexp of regexp * ppat | Regexp of regexp * ppat
(* regular expression, continuation: [ re ; cont ], e.g: [ re ; nil ] *) (* regular expression, continuation: [ re ; cont ], e.g: [ re ; nil ] *)
...@@ -112,4 +110,4 @@ and regexp = ...@@ -112,4 +110,4 @@ and regexp =
| WeakStar of regexp | WeakStar of regexp
| SeqCapture of id * regexp | SeqCapture of id * regexp
open Printf
(* TODO: handle encodings of the input for pretty printing
fragments of code *)
type source = [ `None | `File of string | `Stream | `String of string ] type source = [ `None | `File of string | `Stream | `String of string ]
type loc = source * int * int type loc = source * int * int
type precise = [ `Full | `Char of int ] type precise = [ `Full | `Char of int ]
...@@ -38,18 +41,34 @@ let nopos = (-1,-1) ...@@ -38,18 +41,34 @@ let nopos = (-1,-1)
let viewport = ref `Text let viewport = ref `Text
let set_viewport v = viewport := v let set_viewport v = viewport := v
(* Note: this is incorrect. Directives #utf8,... should
not be recognized inside comments and strings !
The clean solution is probably to have the real lexer
count the lines. *)
let get_line_number src i = let get_line_number src i =
let enc = ref Ulexing.Latin1 in
let ic = open_in_bin src in let ic = open_in_bin src in
let rec aux pos line start = let lb = Ulexing.from_var_enc_channel enc ic in
if (pos >= i) let rec count line start = lexer
then (line,i - start) | '\n' | "\n\r" | '\r' ->
else aux (line + 1) (Ulexing.lexeme_end lb)
match input_char ic with | "#utf8" ->
| '\r' when pos = start -> aux (pos + 1) line (pos + 1) enc := Ulexing.Utf8;
| '\r' | '\n' -> aux (pos + 1) (line + 1) (pos + 1) aux line start
| _ -> aux (pos + 1) line start | "#ascii" ->
enc := Ulexing.Ascii;
aux line start
| "#latin1" ->
enc := Ulexing.Latin1;
aux line start
| _ ->
aux line start
and aux line start =
if (Ulexing.lexeme_start lb >= i) then (line, i - start)
else count line start lb
in in
let r = aux 0 1 0 in let r = aux 1 0 in
close_in ic; close_in ic;
r r
......
...@@ -29,7 +29,6 @@ let top_phrases = Grammar.Entry.create gram "toplevel phrases" ...@@ -29,7 +29,6 @@ let top_phrases = Grammar.Entry.create gram "toplevel phrases"
let expr = Grammar.Entry.create gram "expression" let expr = Grammar.Entry.create gram "expression"
let pat = Grammar.Entry.create gram "type/pattern expression" let pat = Grammar.Entry.create gram "type/pattern expression"
let regexp = Grammar.Entry.create gram "type/pattern regexp" let regexp = Grammar.Entry.create gram "type/pattern regexp"
let const = Grammar.Entry.create gram "scalar constant"
let exp pos e = LocatedExpr (loc_of_pos pos,e) let exp pos e = LocatedExpr (loc_of_pos pos,e)
...@@ -50,7 +49,7 @@ let tuple_queue = ...@@ -50,7 +49,7 @@ let tuple_queue =
let char = mknoloc (Internal (Types.char Chars.any)) let char = mknoloc (Internal (Types.char Chars.any))
let string_regexp = Star (Elem char) let string_regexp = Star (Elem char)
let cst_nil = Cst (Const_internal (Types.Atom Sequence.nil_atom)) let cst_nil = Atom (U.mk "nil")
let pat_nil = mknoloc (Internal (Sequence.nil_type)) let pat_nil = mknoloc (Internal (Sequence.nil_type))
let seq_of_string s = let seq_of_string s =
...@@ -83,7 +82,7 @@ let is_fun_decl = ...@@ -83,7 +82,7 @@ let is_fun_decl =
) )
EXTEND EXTEND
GLOBAL: top_phrases prog expr pat regexp const; GLOBAL: top_phrases prog expr pat regexp;
top_phrases: [ top_phrases: [
[ l = LIST0 phrase; ";;" -> List.flatten l ] [ l = LIST0 phrase; ";;" -> List.flatten l ]
...@@ -265,8 +264,8 @@ EXTEND ...@@ -265,8 +264,8 @@ EXTEND
] ]
| "no_appl" | "no_appl"
[ c = const -> exp loc (Cst c) [
| "("; l = LIST1 expr SEP ","; ")" -> exp loc (tuple l) "("; l = LIST1 expr SEP ","; ")" -> exp loc (tuple l)
| "["; l = LIST0 seq_elem; e = OPT [ ";"; e = expr -> e ]; | "["; l = LIST0 seq_elem; e = OPT [ ";"; e = expr -> e ];
loc_end = ["]" -> loc] -> loc_end = ["]" -> loc] ->
let e = match e with Some e -> e | None -> cst_nil in let e = match e with Some e -> e | None -> cst_nil in
...@@ -282,10 +281,9 @@ EXTEND ...@@ -282,10 +281,9 @@ EXTEND
in in
exp loc l exp loc l
| "<"; t = [ "("; e = expr; ")" -> e | "<"; t = [ "("; e = expr; ")" -> e
| a = tag -> exp loc (Cst a) | a = tag -> exp loc a
]; ];
a = expr_attrib_spec; ">"; c = expr -> a = expr_attrib_spec; ">"; c = expr ->
(* let t = Pair (cst_nil, t) in *)
exp loc (Xml (t, Pair (a,c))) exp loc (Xml (t, Pair (a,c)))
| "{"; r = [ expr_record_spec | -> exp loc (RecordLitt []) ]; "}" -> r | "{"; r = [ expr_record_spec | -> exp loc (RecordLitt []) ]; "}" -> r
| s = STRING2 -> | s = STRING2 ->
...@@ -294,16 +292,18 @@ EXTEND ...@@ -294,16 +292,18 @@ EXTEND
| a = IDENT -> exp loc (Var (ident a)) | a = IDENT -> exp loc (Var (ident a))
| "!"; e = expr -> | "!"; e = expr ->
exp loc (Apply (Dot (e, U.mk "get"), cst_nil)) exp loc (Apply (Dot (e, U.mk "get"), cst_nil))
| i = INT -> exp loc (Integer (Intervals.V.mk i))
| "`"; a = tag -> a
| c = char -> exp loc (Char c)
] ]
]; ];
tag: [ [ a = [ IDENT | keyword ] -> tag: [ [ a = [ IDENT | keyword ] -> exp loc (Atom (parse_ident a)) ] ];
Const_atom (parse_ident a) ] ];
tag_type: [ tag_type: [
[ IDENT "_" -> mk loc (Internal (Types.atom Atoms.any)) [ IDENT "_" -> mk loc (Internal (Types.atom Atoms.any))
| a = [ IDENT | keyword ] -> mk loc (AtomT (parse_ident a)) | a = [ IDENT | keyword ] -> mk loc (Cst (Atom (parse_ident a)))
| t = ANY_IN_NS -> mk loc (NsT (parse_ident t)) | t = ANY_IN_NS -> mk loc (NsT (parse_ident t))
] ]
]; ];
...@@ -399,7 +399,7 @@ EXTEND ...@@ -399,7 +399,7 @@ EXTEND
| x = regexp; "?" -> Alt (x, Epsilon) | x = regexp; "?" -> Alt (x, Epsilon)
| x = regexp; "??" -> Alt (Epsilon, x) ] | x = regexp; "??" -> Alt (Epsilon, x) ]
| [ "("; x = regexp; ")" -> x | [ "("; x = regexp; ")" -> x
| "("; a = IDENT; ":="; c = const; ")" -> | "("; a = IDENT; ":="; c = expr; ")" ->
Elem (mk loc (Constant ((ident a,c)))) Elem (mk loc (Constant ((ident a,c))))
| IDENT "PCDATA" -> string_regexp | IDENT "PCDATA" -> string_regexp
| i = STRING1; "--"; j = STRING1 -> | i = STRING1; "--"; j = STRING1 ->
...@@ -435,7 +435,7 @@ EXTEND ...@@ -435,7 +435,7 @@ EXTEND
let fields = [ label "get", get_fun; label "set", set_fun ] in let fields = [ label "get", get_fun; label "set", set_fun ] in
mk loc (Record (false, fields)) mk loc (Record (false, fields))
| IDENT "_" -> mk loc (Internal Types.any) | IDENT "_" -> mk loc (Internal Types.any)
| "("; a = IDENT; ":="; c = const; ")" -> | "("; a = IDENT; ":="; c = expr; ")" ->
mk loc (Constant (ident a,c)) mk loc (Constant (ident a,c))
| schema = IDENT; "#"; typ = [ IDENT | keyword ]; | schema = IDENT; "#"; typ = [ IDENT | keyword ];
k = OPT [ "as"; k = [ "element" | "type" | "attribute" ] -> k ] -> k = OPT [ "as"; k = [ "element" | "type" | "attribute" ] -> k ] ->
...@@ -468,11 +468,6 @@ EXTEND ...@@ -468,11 +468,6 @@ EXTEND
| i = char ; "--"; j = char -> | i = char ; "--"; j = char ->
mk loc (Internal (Types.char (Chars.char_class i j))) mk loc (Internal (Types.char (Chars.char_class i j)))
| "`"; c = tag_type -> c | "`"; c = tag_type -> c
| c = const ->
(match c with
| Const_atom l -> mk loc (AtomT l)
| Const_internal c -> mk loc (Internal (Types.constant c))
)
| "("; l = LIST1 pat SEP ","; ")" -> multi_prod loc l | "("; l = LIST1 pat SEP ","; ")" -> multi_prod loc l
| "["; r = [ r = regexp -> r | -> Epsilon ]; | "["; r = [ r = regexp -> r | -> Epsilon ];
q = [ ";"; q = pat -> q q = [ ";"; q = pat -> q
...@@ -514,14 +509,6 @@ EXTEND ...@@ -514,14 +509,6 @@ EXTEND
]; ];
const:
[
[ i = INT -> Const_internal (Types.Integer (Intervals.V.mk i))
| "`"; a = tag -> a
| c = char -> Const_internal (Types.Char c) ]
];
attrib_spec: attrib_spec:
[ [ r = LIST0 [ l = [IDENT | keyword ]; "="; [ [ r = LIST0 [ l = [IDENT | keyword ]; "=";
o = [ "?" -> true | -> false]; o = [ "?" -> true | -> false];
...@@ -568,7 +555,7 @@ let sync () = ...@@ -568,7 +555,7 @@ let sync () =
match !Ulexer.last_tok with match !Ulexer.last_tok with
| ("",";;") | ("EOI","") -> () | ("",";;") | ("EOI","") -> ()
| _ -> | _ ->
Ulexer.last_tok := Ulexer.token lb; Ulexer.last_tok := fst (Ulexer.token lb);
aux () aux ()
in in
aux () aux ()
...@@ -57,38 +57,42 @@ let illegal lexbuf = ...@@ -57,38 +57,42 @@ let illegal lexbuf =
let in_comment = ref false let in_comment = ref false
let return lexbuf tok = (tok, L.loc lexbuf)
let return_loc i j tok = (tok, (i,j))
let rec token = lexer let rec token = lexer
| xml_blank+ -> token lexbuf | xml_blank+ -> token lexbuf
| qname -> | qname ->
let s = L.utf8_lexeme lexbuf in let s = L.utf8_lexeme lexbuf in
if Hashtbl.mem keywords s then "",s else "IDENT",s return lexbuf (if Hashtbl.mem keywords s then "",s else "IDENT",s)
| ncname ":*" -> | ncname ":*" ->
let s = L.utf8_sub_lexeme lexbuf 0 (L.lexeme_length lexbuf - 2) in let s = L.utf8_sub_lexeme lexbuf 0 (L.lexeme_length lexbuf - 2) in
"ANY_IN_NS", s