summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perl_checker.src/lexer.mll21
-rw-r--r--perl_checker.src/parser.mly4
2 files changed, 20 insertions, 5 deletions
diff --git a/perl_checker.src/lexer.mll b/perl_checker.src/lexer.mll
index 044c562..a787ac2 100644
--- a/perl_checker.src/lexer.mll
+++ b/perl_checker.src/lexer.mll
@@ -40,7 +40,7 @@ type raw_token =
| RAW_IDENT_PAREN of (string option * string * raw_pos)
| ARRAYLEN_IDENT of (string option * string * raw_pos)
| SUB_WITH_PROTO of (string * raw_pos)
- | FUNC_DECL_WITH_PROTO of (string * string * raw_pos)
+ | FUNC_DECL_WITH_PROTO of (string option * string * string * raw_pos)
| IF of raw_pos | ELSIF of raw_pos | ELSE of raw_pos | UNLESS of raw_pos | DO of raw_pos | WHILE of raw_pos | UNTIL of raw_pos | MY_OUR of (string * raw_pos) | CONTINUE of raw_pos | SUB of raw_pos
| LOCAL of raw_pos | FOR of (string * raw_pos) | USE of raw_pos | PACKAGE of raw_pos | BEGIN of raw_pos | END of raw_pos | PRINT of (string * raw_pos)
@@ -98,7 +98,7 @@ let rec raw_token_to_pos_and_token spaces = function
| RAW_IDENT_PAREN(kind, name, pos) -> pos, Parser.RAW_IDENT_PAREN(new_any M_special (kind, name) spaces pos)
| ARRAYLEN_IDENT(kind, name, pos) -> pos, Parser.ARRAYLEN_IDENT(new_any M_special (kind, name) spaces pos)
| SUB_WITH_PROTO(proto, pos) -> pos, Parser.SUB_WITH_PROTO(new_any M_special proto spaces pos)
- | FUNC_DECL_WITH_PROTO(name, proto, pos) -> pos, Parser.FUNC_DECL_WITH_PROTO(new_any M_special (name, proto) spaces pos)
+ | FUNC_DECL_WITH_PROTO(fq, name, proto, pos) -> pos, Parser.FUNC_DECL_WITH_PROTO(new_any M_special (fq, name, proto) spaces pos)
| NEW(pos) -> pos, Parser.NEW(new_any M_special () spaces pos)
| FORMAT(pos) -> pos, Parser.FORMAT(new_any M_special () spaces pos)
@@ -601,7 +601,22 @@ rule token = parse
let ident = String.sub s ident_start (ident_end - ident_start + 1) in
let prototype = skip_n_char_ (proto_start + 1) 1 s in
- FUNC_DECL_WITH_PROTO(ident, prototype, pos lexbuf)
+ FUNC_DECL_WITH_PROTO(None, ident, prototype, pos lexbuf)
+ }
+
+| "sub" ' '+ ident ("::" ident)+ ' '* '(' [ '$' '@' '\\' '&' ';' '%' ]* ')' {
+ (* bloody prototypes, must be caught especially otherwise "($)" is badly tokenized *)
+ (* and alas "($@)" is both valid as an expression and a prototype *)
+ let s = lexeme lexbuf in
+ let ident_start = non_index_from s 3 ' ' in
+
+ let proto_start = String.index_from s ident_start '(' in
+ let ident_end = non_rindex_from s (proto_start-1) ' ' in
+ let ident = String.sub s ident_start (ident_end - ident_start + 1) in
+ let prototype = skip_n_char_ (proto_start + 1) 1 s in
+
+ let fq, name = split_at_two_colons ident in
+ FUNC_DECL_WITH_PROTO(Some fq, name, prototype, pos lexbuf)
}
| "$#" ident? ("::" ident)+ { arraylen_fqident_from_lexbuf lexbuf }
diff --git a/perl_checker.src/parser.mly b/perl_checker.src/parser.mly
index d2a8cc9..ed2095d 100644
--- a/perl_checker.src/parser.mly
+++ b/perl_checker.src/parser.mly
@@ -24,7 +24,7 @@
%token <(string option * string) Types.any_spaces_pos> SCALAR_IDENT ARRAY_IDENT HASH_IDENT FUNC_IDENT STAR_IDENT RAW_IDENT RAW_IDENT_PAREN ARRAYLEN_IDENT
%token <string Types.any_spaces_pos> SUB_WITH_PROTO
-%token <(string * string) Types.any_spaces_pos> FUNC_DECL_WITH_PROTO
+%token <(string option * string * string) Types.any_spaces_pos> FUNC_DECL_WITH_PROTO
%token <string Types.any_spaces_pos> FOR PRINT
%token <unit Types.any_spaces_pos> NEW FORMAT
@@ -181,7 +181,7 @@ use_revision:
func_decl:
| SUB word { new_esp M_none ($2.any, None) $1 $2}
-| FUNC_DECL_WITH_PROTO {new_1esp (Ident(None, fst $1.any, get_pos $1), Some (snd $1.any)) $1 }
+| FUNC_DECL_WITH_PROTO {new_1esp (Ident(fst3 $1.any, snd3 $1.any, get_pos $1), Some (ter3 $1.any)) $1 }
listexpr: /* Basic list expressions */
| %prec PREC_LOW { default_pesp P_tok []}