Explorar el Código

[parser] allow parsing `@a.b`

closes #3959
Simon Krajewski hace 7 años
padre
commit
f85c1e1ff5
Se han modificado 3 ficheros con 17 adiciones y 8 borrados
  1. 1 0
      extra/CHANGES.txt
  2. 14 8
      src/syntax/grammar.mly
  3. 2 0
      src/syntax/parser.ml

+ 1 - 0
extra/CHANGES.txt

@@ -7,6 +7,7 @@ XXXX-XX-XX: 4.0.0-preview.4
 	General improvements and optimizations:
 
 	all : implemented `for` loop unrolling (#3784)
+	all : metadata can now use `.`, e.g. `@:a.b`. This is represented as a string (#3959)
 	js : added externs for js.Date (#6855)
 	js : respect `-D source-map` flag to generate source maps in release builds
 

+ 14 - 8
src/syntax/grammar.mly

@@ -351,7 +351,7 @@ and parse_meta_params pname s = match s with parser
 and parse_meta_entry = parser
 	[< '(At,p1); s >] ->
 		match s with parser
-		| [< name,p = meta_name p1; params = parse_meta_params p; s >] -> (name,params,p)
+		| [< name,p = parse_meta_name p1; params = parse_meta_params p; s >] -> (name,params,p)
 		| [< >] ->
 			if is_resuming p1 then (Meta.Last,[],p1) else serror()
 
@@ -360,13 +360,19 @@ and parse_meta = parser
 		entry :: parse_meta s
 	| [< >] -> []
 
-and meta_name p1 = parser
-	| [< '(Const (Ident i),p) when p.pmin = p1.pmax >] -> (Meta.Custom i), p
-	| [< '(Kwd k,p) when p.pmin = p1.pmax >] -> (Meta.Custom (s_keyword k)),p
-	| [< '(DblDot,p) when p.pmin = p1.pmax; s >] -> match s with parser
-		| [< '(Const (Ident i),p1) when p1.pmin = p.pmax >] -> (Meta.parse i),punion p p1
-		| [< '(Kwd k,p1) when p1.pmin = p.pmax >] -> (Meta.parse (s_keyword k)),punion p p1
-		| [< >] -> if is_resuming p then Meta.Last,p else raise Stream.Failure
+and parse_meta_name_2 p1 acc s =
+	let part,p = match s with parser
+		| [< '(Const (Ident i),p) when p.pmin = p1.pmax >] -> i,p
+		| [< '(Kwd k,p) when p.pmin = p1.pmax >] -> s_keyword k,p
+	in
+	let acc = part :: acc in
+	match s with parser
+	| [< '(Dot,p1); part,p2 = parse_meta_name_2 p1 acc >] -> part,punion p p2
+	| [< >] -> acc,p
+
+and parse_meta_name p1 = parser
+	| [< '(DblDot,p) when p.pmin = p1.pmax; name,p2 = parse_meta_name_2 p [] >] -> (Meta.parse (rev_concat "." name)),p2
+	| [< name,p2 = parse_meta_name_2 p1 [] >] -> (Meta.Custom (rev_concat "." name)),p2
 
 and parse_enum_flags = parser
 	| [< '(Kwd Enum,p) >] -> [] , p

+ 2 - 0
src/syntax/parser.ml

@@ -130,6 +130,8 @@ let is_dollar_ident e = match fst e with
 	| _ ->
 		false
 
+let rev_concat s sl = String.concat s (List.rev sl)
+
 let precedence op =
 	let left = true and right = false in
 	match op with