summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perl_checker.src/lexer.mll1
-rw-r--r--perl_checker.src/parser.mly28
-rw-r--r--perl_checker.src/parser_helper.ml12
-rw-r--r--perl_checker.src/parser_helper.mli1
-rw-r--r--perl_checker.src/types.mli1
5 files changed, 25 insertions, 18 deletions
diff --git a/perl_checker.src/lexer.mll b/perl_checker.src/lexer.mll
index a9de7d2..7de0f13 100644
--- a/perl_checker.src/lexer.mll
+++ b/perl_checker.src/lexer.mll
@@ -540,6 +540,7 @@ rule token = parse
| "printf" { PRINT(lexeme lexbuf, pos lexbuf) }
| "new" { NEW(pos lexbuf) }
| "format" { let pos = pos lexbuf in FORMAT(here_doc_next_line ".", pos) }
+| "delete"
| "defined"
| "length"
| "keys"
diff --git a/perl_checker.src/parser.mly b/perl_checker.src/parser.mly
index 549cef2..e44bcf1 100644
--- a/perl_checker.src/parser.mly
+++ b/perl_checker.src/parser.mly
@@ -319,20 +319,20 @@ term:
| array BRACKET expr BRACKET_END {sp_0($2); sp_0($3); sp_0($4); new_pesp M_list P_expr (to_Deref_with(I_hash, I_array, from_array $1, $3.any.expr)) $1 $4} /* hash slice: @hash{@keys} */
/* function_calls */
-| ONE_SCALAR_PARA RAW_STRING {call_one_scalar_para $1 [to_Raw_string $2] $1 $2}
-| ONE_SCALAR_PARA STRING {call_one_scalar_para $1 [to_String true $2] $1 $2}
-| ONE_SCALAR_PARA variable {call_one_scalar_para $1 [$2.any] $1 $2}
-| ONE_SCALAR_PARA restricted_subscripted {call_one_scalar_para $1 [$2.any] $1 $2}
-| ONE_SCALAR_PARA parenthesized {call_one_scalar_para $1 $2.any.expr $1 $2}
-| ONE_SCALAR_PARA BRACKET lines BRACKET_END {sp_n($2); new_pesp M_unknown P_tok (call(Deref(I_func, Ident(None, $1.any, raw_pos2pos $1.pos)), [anonymous_sub None $3 $4])) $1 $4} /* eval { foo } */
-| ONE_SCALAR_PARA diamond {call_one_scalar_para $1 [$2.any] $1 $2}
-| ONE_SCALAR_PARA %prec PREC_LOW {call_one_scalar_para $1 [] $1 $1}
-| ONE_SCALAR_PARA word argexpr {check_parenthesized_first_argexpr_with_Ident $2.any $3; call_one_scalar_para $1 [call(Deref(I_func, $2.any), $3.any.expr)] $1 $3} /* ref foo $a, $b */
-| ONE_SCALAR_PARA hash PKG_SCOPE {sp_0($3); call_one_scalar_para $1 [ Call(Too_complex, [$2.any]) ] $1 $3} /* keys %main:: */
-| ONE_SCALAR_PARA BAREWORD {if $2.any = "_" && $1.any.[0] = '-' then new_pesp M_bool P_mul Too_complex $1 $2 else die_rule "syntax error"} /* -e "foo" && -f _ */
-
-| ONE_SCALAR_PARA array arrayref {call_one_scalar_para $1 [to_Deref_with(I_array, I_array, from_array $2, List $3.any)] $1 $3} /* array slice: @array[vals] */
-| ONE_SCALAR_PARA array BRACKET expr BRACKET_END {sp_0($3); sp_0($4); sp_0($5); call_one_scalar_para $1 [to_Deref_with(I_hash, I_array, from_array $2, $4.any.expr)] $1 $5} /* hash slice: @hash{@keys} */
+| ONE_SCALAR_PARA RAW_STRING {call_one_scalar_para P_uniop $1 [to_Raw_string $2] $1 $2}
+| ONE_SCALAR_PARA STRING {call_one_scalar_para P_uniop $1 [to_String true $2] $1 $2}
+| ONE_SCALAR_PARA variable {call_one_scalar_para P_uniop $1 [$2.any] $1 $2}
+| ONE_SCALAR_PARA restricted_subscripted {call_one_scalar_para P_uniop $1 [$2.any] $1 $2}
+| ONE_SCALAR_PARA parenthesized {call_one_scalar_para P_tok $1 $2.any.expr $1 $2}
+| ONE_SCALAR_PARA BRACKET lines BRACKET_END {sp_n($2); new_pesp M_unknown P_uniop (call(Deref(I_func, Ident(None, $1.any, raw_pos2pos $1.pos)), [anonymous_sub None $3 $4])) $1 $4} /* eval { foo } */
+| ONE_SCALAR_PARA diamond {call_one_scalar_para P_uniop $1 [$2.any] $1 $2}
+| ONE_SCALAR_PARA %prec PREC_LOW {call_one_scalar_para P_tok $1 [] $1 $1}
+| ONE_SCALAR_PARA word argexpr {check_parenthesized_first_argexpr_with_Ident $2.any $3; call_one_scalar_para P_uniop $1 [call(Deref(I_func, $2.any), $3.any.expr)] $1 $3} /* ref foo $a, $b */
+| ONE_SCALAR_PARA hash PKG_SCOPE {sp_0($3); call_one_scalar_para P_uniop $1 [ Call(Too_complex, [$2.any]) ] $1 $3} /* keys %main:: */
+| ONE_SCALAR_PARA BAREWORD {if $2.any = "_" && $1.any.[0] = '-' then new_pesp M_bool P_uniop Too_complex $1 $2 else die_rule "syntax error"} /* -e "foo" && -f _ */
+
+| ONE_SCALAR_PARA array arrayref {call_one_scalar_para P_uniop $1 [to_Deref_with(I_array, I_array, from_array $2, List $3.any)] $1 $3} /* array slice: @array[vals] */
+| ONE_SCALAR_PARA array BRACKET expr BRACKET_END {sp_0($3); sp_0($4); sp_0($5); call_one_scalar_para P_uniop $1 [to_Deref_with(I_hash, I_array, from_array $2, $4.any.expr)] $1 $5} /* hash slice: @hash{@keys} */
| func parenthesized {sp_0($2); call_func $1 $2} /* &foo(@args) */
| word argexpr {check_parenthesized_first_argexpr_with_Ident $1.any $2; call_no_paren $1 $2} /* foo $a, $b */
diff --git a/perl_checker.src/parser_helper.ml b/perl_checker.src/parser_helper.ml
index 731b78f..43d60a4 100644
--- a/perl_checker.src/parser_helper.ml
+++ b/perl_checker.src/parser_helper.ml
@@ -317,6 +317,8 @@ let rec prio_less = function
| P_eq, _ -> false
| _, P_cmp -> true
| P_cmp, _ -> false
+ | _, P_uniop -> true
+ | P_uniop, _ -> false
| _, P_add -> true
| P_add, _ -> false
| _, P_mul -> true
@@ -337,8 +339,10 @@ let prio_lo_check pri_out pri_in pos expr =
prio_less(pri_in', pri_out) && not_complex (un_parenthesize expr) then
warn [Warn_suggest_simpler] pos "unneeded parentheses"
| _ -> ())
- else
+ else
(match expr with
+ | Call(Deref(I_func, Ident(None, f, _)), _) when f <> "delete" && pri_in = P_uniop && pri_out = P_add
+ -> () (* ugly special case since we don't parse uniop correctly (eg: -d $_ . "foo" *)
| Call_op ("print", [Deref (I_star, Ident (None, "STDOUT", _)); (Deref(I_scalar, _) as ident)], _) ->
warn [Warn_traps] pos (sprintf "use parentheses: replace \"print %s ...\" with \"print(%s ...)\"" (string_of_fromparser ident) (string_of_fromparser ident))
| _ -> warn [Warn_traps] pos "missing parentheses (needed for clarity)")
@@ -1088,8 +1092,8 @@ let call_with_paren esp_func esp_para = check_return esp_func esp_para; call_and
let call_func esp_func esp_para =
call_and_context(esp_func.any, esp_para.any.expr) true P_tok esp_func esp_para
-let call_one_scalar_para { any = e ; pos = pos } para esp_start esp_end =
- let para =
+let call_one_scalar_para prio { any = e ; pos = pos } para esp_start esp_end =
+ let para' =
match para with
| [] ->
if e = "shift" || e = "pop" then
@@ -1099,7 +1103,7 @@ let call_one_scalar_para { any = e ; pos = pos } para esp_start esp_end =
[var_dollar_ (raw_pos2pos pos)])
| _ -> para
in
- new_pesp M_unknown P_mul (call(Deref(I_func, Ident(None, e, raw_pos2pos pos)), para)) esp_start esp_end
+ new_pesp M_unknown prio (call(Deref(I_func, Ident(None, e, raw_pos2pos pos)), para')) esp_start esp_end
let (current_lexbuf : Lexing.lexbuf option ref) = ref None
diff --git a/perl_checker.src/parser_helper.mli b/perl_checker.src/parser_helper.mli
index 0708792..e820703 100644
--- a/perl_checker.src/parser_helper.mli
+++ b/perl_checker.src/parser_helper.mli
@@ -235,6 +235,7 @@ val call_func :
Types.fromparser list Types.prio_anyexpr Types.any_spaces_pos ->
Types.fromparser Types.prio_anyexpr Types.any_spaces_pos
val call_one_scalar_para :
+ Types.priority ->
string Types.any_spaces_pos ->
Types.fromparser list ->
'a Types.any_spaces_pos ->
diff --git a/perl_checker.src/types.mli b/perl_checker.src/types.mli
index 15f97cd..5f23d3a 100644
--- a/perl_checker.src/types.mli
+++ b/perl_checker.src/types.mli
@@ -72,6 +72,7 @@ type priority =
| P_tight
| P_mul
| P_add
+| P_uniop
| P_cmp
| P_eq
| P_expr