summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perl_checker.src/parser.mly124
-rw-r--r--perl_checker.src/parser_helper.ml44
-rw-r--r--perl_checker.src/parser_helper.mli20
-rw-r--r--perl_checker.src/types.mli1
4 files changed, 117 insertions, 72 deletions
diff --git a/perl_checker.src/parser.mly b/perl_checker.src/parser.mly
index e94f622..dfbbd2f 100644
--- a/perl_checker.src/parser.mly
+++ b/perl_checker.src/parser.mly
@@ -103,7 +103,7 @@ line:
| if_then_else {$1}
| loop {$1}
| LABEL {sp_cr($1); Label(fst $1), snd $1}
-| semi_colon {List [], snd $1}
+| semi_colon {Semi_colon, snd $1}
| sideff semi_colon {$1}
| BRACKET lines BRACKET_END {sp_p($2); sp_p($3); Block(fst $2), snd $1}
@@ -113,7 +113,7 @@ if_then_else: /* Real conditional expressions */
elsif:
| {[], (Space_none, bpos)}
-| ELSIF PAREN expr PAREN_END BRACKET lines BRACKET_END elsif {sp_p($1); sp_n($2); sp_0($3); sp_0_or_cr($4); sp_p($5); sp_p($7); fst $3 :: Block(fst $6) :: fst $8, snd $1}
+| ELSIF PAREN expr PAREN_END BRACKET lines BRACKET_END elsif {sp_p($1); sp_n($2); sp_0($3); sp_0_or_cr($4); sp_p($5); sp_p($6); sp_p($7); fst $3 :: Block(fst $6) :: fst $8, snd $1}
else_:
| { [], (Space_none, bpos) }
@@ -129,7 +129,7 @@ loop:
cont: /* Continue blocks */
| {(), (Space_none, bpos)}
-| CONTINUE BRACKET lines BRACKET_END {sp_p($1); sp_n($2); sp_p($4); (), snd $1}
+| CONTINUE BRACKET lines BRACKET_END {sp_p($1); sp_n($2); sp_p($3); sp_p($4); (), snd $1}
sideff: /* An expression which may have a side-effect */
| expr {$1}
@@ -144,16 +144,16 @@ decl:
| FORMAT ASSIGN {Too_complex, snd $1}
| func_decl semi_colon {die_rule (if snd (fst $1) = "" then "there is no need to pre-declare in Perl!" else "please don't use prototype pre-declaration") }
| func_decl BRACKET BRACKET_END {sp_n($2); sp_0_or_cr($3); let name, proto = fst $1 in sub_declaration (name, proto) [], snd $1}
-| func_decl BRACKET lines BRACKET_END {sp_n($2); sp_p($3); sp_p($4); sub_declaration (fst $1) (fst $3), snd $1}
+| func_decl BRACKET lines BRACKET_END {sp_n($2); check_lines_after_BRACKET($3); sp_p($4); sub_declaration (fst $1) (fst $3), snd $1}
| func_decl BRACKET BRACKET expr BRACKET_END BRACKET_END {sp_n($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); sub_declaration (fst $1) [Ref(I_hash, fst $4)], snd $1}
| func_decl BRACKET BRACKET expr BRACKET_END semi_colon BRACKET_END {sp_n($2); sp_p($3); sp_p($4); sp_p($5); sp_p($7); sub_declaration (fst $1) [Ref(I_hash, fst $4)], snd $1}
-| PACKAGE word semi_colon {sp_0_or_cr($1); Package(fst $2), snd $1}
+| PACKAGE word semi_colon {sp_0_or_cr($1); sp_1($2); Package(fst $2), snd $1}
| BEGIN BRACKET lines BRACKET_END {sp_0_or_cr($1); sp_1($2); sp_p($3); sp_p($4); Sub_declaration(Ident(None, "BEGIN", get_pos $1), "", fst $3), snd $1}
| END BRACKET lines BRACKET_END {sp_0_or_cr($1); sp_1($2); sp_p($3); sp_p($4); Sub_declaration(Ident(None, "END", get_pos $1), "", fst $3), snd $1}
| use {$1}
use:
-| use_word listexpr semi_colon {Use(fst $1, fst $2), snd $1}
+| use_word listexpr semi_colon {sp_n($2); Use(fst $1, fst $2), snd $1}
use_word:
| use_revision word comma {fst $2, snd $1}
@@ -180,20 +180,20 @@ expr: /* Ordinary expressions; logical combinations */
argexpr: /* Expressions are a list of terms joined by commas */
| argexpr comma {fst $1, snd $1}
-| argexpr comma term {fst $1 @ [fst $3], snd $1}
+| argexpr comma term {if not_simple (fst $3) then sp_p($3); fst $1 @ [fst $3], snd $1}
| argexpr comma BRACKET expr BRACKET_END {sp_p($3); sp_p($5); fst $1 @ [ Ref(I_hash, fst $4) ], snd $1}
| term %prec PREC_LOW {[fst $1], snd $1}
/********************************************************************************/
term:
-| term binop term {Call_op(fst $2, [fst $1 ; fst $3]), snd $1}
-| term binop BRACKET expr BRACKET_END {sp_p($3); sp_p($5); Call_op(fst $2, [fst $1 ; Ref(I_hash, fst $4)]), snd $1}
-| term LT term {Call_op("<", [fst $1 ; fst $3]), snd $1}
-| term GT term {Call_op(">", [fst $1 ; fst $3]), snd $1}
+| term binop term {call_op(fst $2, $3, [fst $1 ; fst $3]), snd $1}
+| term binop BRACKET expr BRACKET_END {sp_p($3); sp_p($4); sp_p($5); call_op(fst $2, $3, [fst $1 ; Ref(I_hash, fst $4)]), snd $1}
+| term LT term {sp_n($2); sp_p($3); Call_op("<", [fst $1 ; fst $3]), snd $1}
+| term GT term {sp_n($2); sp_p($3); Call_op(">", [fst $1 ; fst $3]), snd $1}
-| term PATTERN_MATCH PATTERN {Call_op("m//", fst $1 :: from_PATTERN $3), snd $1}
-| term PATTERN_MATCH_NOT PATTERN {Call_op("!m//", fst $1 :: from_PATTERN $3), snd $1}
-| term PATTERN_MATCH PATTERN_SUBST {Call_op("s///", fst $1 :: from_PATTERN_SUBST $3), snd $1}
+| term PATTERN_MATCH PATTERN {sp_n($2); sp_p($3); Call_op("m//", fst $1 :: from_PATTERN $3), snd $1}
+| term PATTERN_MATCH_NOT PATTERN {sp_n($2); sp_p($3); Call_op("!m//", fst $1 :: from_PATTERN $3), snd $1}
+| term PATTERN_MATCH PATTERN_SUBST {sp_n($2); sp_p($3); Call_op("s///", fst $1 :: from_PATTERN_SUBST $3), snd $1}
| term PATTERN_MATCH scalar { Too_complex, snd $1 }
| term PATTERN_MATCH_NOT scalar { Too_complex, snd $1 }
@@ -202,11 +202,11 @@ term:
| term PATTERN_MATCH_NOT STRING {failwith (msg_with_pos (snd (snd $3)) "use a regexp, not a string")}
/* Unary operators and terms */
-| MINUS term %prec UNARY_MINUS {Call_op("- unary", [fst $2]), snd $1}
+| MINUS term %prec UNARY_MINUS {sp_0($2); Call_op("- unary", [fst $2]), snd $1}
| TIGHT_NOT term {Call_op("not", [fst $2]), snd $1}
| BIT_NEG term {Call_op("~", [fst $2]), snd $1}
-| INCR term {Call_op("++", [fst $2]), snd $1}
-| DECR term {Call_op("--", [fst $2]), snd $1}
+| INCR term {sp_0($2); Call_op("++", [fst $2]), snd $1}
+| DECR term {sp_0($2); Call_op("--", [fst $2]), snd $1}
| term INCR {sp_0($2); Call_op("++ post", [fst $1]), snd $1}
| term DECR {sp_0($2); Call_op("-- post", [fst $1]), snd $1}
@@ -223,35 +223,35 @@ term:
| BRACKET BRACKET_END {Ref(I_hash, List []), snd $1} /* empty hash */
| BRACKET_HASHREF expr BRACKET_END %prec PREC_HIGH {sp_p($3); Ref(I_hash, fst $2), snd $1} /* { foo => "Bar" } */
| SUB BRACKET BRACKET_END %prec PREC_HIGH {sp_n($2); sp_0($3); Anonymous_sub(Block[]), snd $1}
-| SUB BRACKET lines BRACKET_END %prec PREC_HIGH {sp_n($2); sp_p($4); Anonymous_sub(Block(fst $3)), snd $1}
+| SUB BRACKET lines BRACKET_END %prec PREC_HIGH {sp_n($2); check_lines_after_BRACKET($3); sp_p($4); Anonymous_sub(Block(fst $3)), snd $1}
| termdo {$1}
| term question_mark_ colon_ { Call_op("?:", [ fst $1 ; fst $2; fst $3]), snd $1}
| REF term { Ref(I_scalar, fst $2), snd $1} /* \$x, \@y, \%z */
| my %prec UNIOP {List(fst $1), snd $1}
-| LOCAL term %prec UNIOP {Local(fst $2), snd $1}
+| LOCAL term %prec UNIOP {sp_n($2); Local(fst $2), snd $1}
| parenthesized {List(fst $1), snd $1} /* (1, 2) */
-| parenthesized arrayref {Deref_with(I_array, List(fst $1), List(fst $2)), snd $1} /* list slice */
+| parenthesized arrayref {sp_0($2); Deref_with(I_array, List(fst $1), List(fst $2)), snd $1} /* list slice */
| variable {$1}
| subscripted {$1}
| array arrayref { Deref_with(I_array, fst $1, List(fst $2)), snd $1} /* array slice: @array[vals] */
-| array BRACKET expr BRACKET_END {sp_0($2); sp_0($4); Deref_with(I_hash, array_ident_to_hash_ident $1, fst $3), snd $1} /* hash slice: @hash{@keys} */
+| array BRACKET expr BRACKET_END {sp_0($2); sp_0($3); sp_0($4); Deref_with(I_hash, array_ident_to_hash_ident $1, fst $3), snd $1} /* hash slice: @hash{@keys} */
/* function_calls */
-| func parenthesized {Call(fst $1, fst $2), snd $1} /* &foo(@args) */
+| func parenthesized {sp_0($2); Call(fst $1, fst $2), snd $1} /* &foo(@args) */
| word argexpr {check_parenthesized_first_argexpr (string_of_Ident (fst $1)) $2; Call(fst $1, fst $2), snd $1} /* foo $a, $b */
| word_paren parenthesized {Call(fst $1, fst $2), snd $1} /* foo(@args) */
-| word BRACKET lines BRACKET_END listexpr %prec LSTOP {sp_n($2); sp_p($4); Call(fst $1, Anonymous_sub(Block(fst $3)) :: fst $5), snd $1} /* map { foo } @bar */
-| word BRACKET BRACKET expr BRACKET_END BRACKET_END listexpr %prec LSTOP {sp_n($2); sp_p($3); sp_p($5); sp_p($6); Call(fst $1, Anonymous_sub(Ref(I_hash, fst $4)) :: fst $7), snd $1} /* map { { foo } } @bar */
-| word BRACKET BRACKET expr BRACKET_END semi_colon BRACKET_END listexpr %prec LSTOP {sp_n($2); sp_p($3); sp_p($5); sp_p($7); Call(fst $1, Anonymous_sub(Ref(I_hash, fst $4)) :: fst $8), snd $1} /* map { { foo }; } @bar */
+| word BRACKET lines BRACKET_END listexpr %prec LSTOP {sp_n($2); check_lines_after_BRACKET($3); sp_p($4); Call(fst $1, Anonymous_sub(Block(fst $3)) :: fst $5), snd $1} /* map { foo } @bar */
+| word BRACKET BRACKET expr BRACKET_END BRACKET_END listexpr %prec LSTOP {sp_n($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); Call(fst $1, Anonymous_sub(Ref(I_hash, fst $4)) :: fst $7), snd $1} /* map { { foo } } @bar */
+| word BRACKET BRACKET expr BRACKET_END semi_colon BRACKET_END listexpr %prec LSTOP {sp_n($2); sp_p($3); sp_p($4); sp_p($5); sp_p($7); Call(fst $1, Anonymous_sub(Ref(I_hash, fst $4)) :: fst $8), snd $1} /* map { { foo }; } @bar */
-| term ARROW word_or_scalar parenthesized {sp_0($2); Method_call(fst $1, fst $3, fst $4), snd $1} /* $foo->bar(list) */
-| term ARROW word_or_scalar {sp_0($2); Method_call(fst $1, fst $3, []), snd $1} /* $foo->bar */
+| term ARROW word_or_scalar parenthesized {sp_0($2); sp_0($3); sp_0($4); Method_call(fst $1, fst $3, fst $4), snd $1} /* $foo->bar(list) */
+| term ARROW word_or_scalar {sp_0($2); sp_0($3); Method_call(fst $1, fst $3, []), snd $1} /* $foo->bar */
| NEW word listexpr { Method_call(fst $2, Ident(None, "new", get_pos $1), fst $3), snd $1} /* new Class @args */
@@ -261,7 +261,7 @@ term:
| PRINT_TO_SCALAR { Call_op("print", var_STDOUT :: [ Deref(I_scalar, Ident(None, fst $1, get_pos $1)) ]), snd $1 }
| PRINT_TO_SCALAR argexpr { Call_op("print", Deref(I_scalar, Ident(None, fst $1, get_pos $1)) :: fst $2), snd $1 }
-| word {$1}
+| word {check_word_alone $1, snd $1}
| NUM {Num(fst $1, get_pos $1), snd $1}
| STRING {to_String $1, snd $1}
@@ -275,18 +275,18 @@ term:
diamond:
| LT GT {sp_0($2); Call_op("<>", []), snd $1}
-| LT term GT {sp_0($3); Call_op("<>", [fst $2]), snd $1}
+| LT term GT {sp_0($2); sp_0($3); Call_op("<>", [fst $2]), snd $1}
subscripted: /* Some kind of subscripted expression */
-| variable PKG_SCOPE bracket_subscript {sp_0($2); Too_complex, snd $1} /* $foo::{something} */
-| scalar bracket_subscript {Deref_with(I_hash , fst $1, fst $2), snd $1} /* $foo{bar} */
-| scalar arrayref {Deref_with(I_array, fst $1, only_one $2), snd $1} /* $array[$element] */
-| term ARROW bracket_subscript {sp_0($2); Deref_with(I_hash , fst $1, fst $3), snd $1} /* somehref->{bar} */
-| term ARROW arrayref {sp_0($2); Deref_with(I_array, fst $1, only_one $3), snd $1} /* somearef->[$element] */
-| term ARROW parenthesized {sp_0($2); Deref_with(I_func , fst $1, List(fst $3)), snd $1} /* $subref->(@args) */
-| subscripted bracket_subscript {Deref_with(I_hash , fst $1, fst $2), snd $1} /* $foo->[bar]{baz} */
-| subscripted arrayref {Deref_with(I_array, fst $1, only_one $2), snd $1} /* $foo->[$bar][$baz] */
-| subscripted parenthesized {Deref_with(I_func , fst $1, List(fst $2)), snd $1} /* $foo->{bar}(@args) */
+| variable PKG_SCOPE bracket_subscript {sp_0($2); sp_0($3); Too_complex, snd $1} /* $foo::{something} */
+| scalar bracket_subscript {sp_0($2); Deref_with(I_hash , fst $1, fst $2), snd $1} /* $foo{bar} */
+| scalar arrayref {sp_0($2); Deref_with(I_array, fst $1, only_one $2), snd $1} /* $array[$element] */
+| term ARROW bracket_subscript {sp_0($2); sp_0($3); Deref_with(I_hash , fst $1, fst $3), snd $1} /* somehref->{bar} */
+| term ARROW arrayref {sp_0($2); sp_0($3); Deref_with(I_array, fst $1, only_one $3), snd $1} /* somearef->[$element] */
+| term ARROW parenthesized {sp_0($2); sp_0($3); Deref_with(I_func , fst $1, List(fst $3)), snd $1} /* $subref->(@args) */
+| subscripted bracket_subscript {sp_0($2); Deref_with(I_hash , fst $1, fst $2), snd $1} /* $foo->[bar]{baz} */
+| subscripted arrayref {sp_0($2); Deref_with(I_array, fst $1, only_one $2), snd $1} /* $foo->[$bar][$baz] */
+| subscripted parenthesized {sp_0($2); Deref_with(I_func , fst $1, List(fst $2)), snd $1} /* $foo->{bar}(@args) */
arrayref:
| arrayref_start ARRAYREF_END {sp_0($2); fst $1, snd $1}
@@ -299,10 +299,10 @@ parenthesized:
arrayref_start:
| ARRAYREF {[], snd $1}
-| arrayref_start BRACKET expr BRACKET_END comma {sp_p($4); fst $1 @ [Ref(I_hash, fst $3)], snd $1}
+| arrayref_start BRACKET expr BRACKET_END comma {sp_p($2); sp_p($3); sp_p($4); fst $1 @ [Ref(I_hash, fst $3)], snd $1}
parenthesized_start:
| PAREN {[], snd $1}
-| parenthesized_start BRACKET expr BRACKET_END comma {sp_p($4); fst $1 @ [Ref(I_hash, fst $3)], snd $1}
+| parenthesized_start BRACKET expr BRACKET_END comma {(if fst $1 = [] then sp_0_or_cr else sp_p)($2); sp_p($3); sp_p($4); fst $1 @ [Ref(I_hash, fst $3)], snd $1}
my: /* Things that can be "my"'d */
| MY parenthesized {List.map (fun e -> My e) (fst $2), snd $1}
@@ -312,32 +312,32 @@ my: /* Things that can be "my"'d */
termdo: /* Things called with "do" */
| DO term %prec UNIOP { die_rule "\"do EXPR\" not allowed" } /* do $filename */
-| DO BRACKET lines BRACKET_END %prec PREC_HIGH {sp_n($2); sp_p($4); Block(fst $3), snd $1} /* do { code */
+| DO BRACKET lines BRACKET_END %prec PREC_HIGH {sp_n($2); check_lines_after_BRACKET($3); sp_p($4); Block(fst $3), snd $1} /* do { code */
question_mark_:
| QUESTION_MARK term {sp_n($1); fst $2, snd $1}
| QUESTION_MARK BRACKET expr BRACKET_END {sp_n($1); sp_p($2); sp_p($4); Ref(I_hash, fst $3), snd $1}
colon_:
-| COLON term {sp_n($1); fst $2, snd $1}
-| COLON BRACKET expr BRACKET_END {sp_n($1); sp_p($2); sp_p($4); Ref(I_hash, fst $3), snd $1}
+| COLON term {sp_p($1); fst $2, snd $1}
+| COLON BRACKET expr BRACKET_END {sp_p($1); sp_p($2); sp_p($3); sp_p($4); Ref(I_hash, fst $3), snd $1}
bracket_subscript:
-| BRACKET expr BRACKET_END {sp_0($1); sp_0($3); only_one_in_List $2, snd $1}
+| BRACKET expr BRACKET_END {sp_0($1); sp_0($2); sp_0($3); only_one_in_List $2, snd $1}
| COMPACT_HASH_SUBSCRIPT {sp_0($1); to_String $1, snd $1}
binop:
-| ASSIGN {"=", snd $1}
-| POWER {"**", snd $1}
-| MULT {"*", snd $1} | DIVISION {"/", snd $1} | MODULO {"%", snd $1} | REPLICATE {"x", snd $1}
-| PLUS {"+", snd $1} | MINUS {"-", snd $1} | CONCAT {".", snd $1}
-| BIT_SHIFT_LEFT {"<<", snd $1} | BIT_SHIFT_RIGHT {">>", snd $1}
-| COMPARE_OP {fst $1, snd $1}
-| EQ_OP {fst $1, snd $1}
-| BIT_AND {"&", snd $1}
-| BIT_OR {"|", snd $1} | BIT_XOR {"^", snd $1}
-| DOTDOT {"..", snd $1} | DOTDOTDOT {"...", snd $1}
-| AND_TIGHT {"&&", snd $1}
-| OR_TIGHT {"||", snd $1} | XOR {"xor", snd $1}
+| ASSIGN {op_p "=" $1, snd $1}
+| POWER {op "**" $1, snd $1}
+| MULT {op "*" $1, snd $1} | DIVISION {op "/" $1, snd $1} | MODULO {op "%" $1, snd $1} | REPLICATE {op_p "x" $1, snd $1}
+| PLUS {op "+" $1, snd $1} | MINUS {op "-" $1, snd $1} | CONCAT {op "." $1, snd $1}
+| BIT_SHIFT_LEFT {op "<<" $1, snd $1} | BIT_SHIFT_RIGHT {op ">>" $1, snd $1}
+| COMPARE_OP {op_p (fst $1) $1, snd $1}
+| EQ_OP {op_p (fst $1) $1, snd $1}
+| BIT_AND {op_p "&" $1, snd $1}
+| BIT_OR {op "|" $1, snd $1} | BIT_XOR {op_p "^" $1, snd $1}
+| DOTDOT {op ".." $1, snd $1} | DOTDOTDOT {op_p "..." $1, snd $1}
+| AND_TIGHT {op_p "&&" $1, snd $1}
+| OR_TIGHT {op_p "||" $1, snd $1} | XOR {op_p "xor" $1, snd $1}
variable:
| scalar %prec PREC_HIGH {$1}
@@ -369,11 +369,11 @@ word_paren:
| BAREWORD_PAREN { Ident(None, fst $1, get_pos $1), snd $1 }
| RAW_IDENT_PAREN { to_Ident $1, snd $1 }
-arraylen: ARRAYLEN_IDENT {Deref(I_arraylen, to_Ident $1), snd $1} | ARRAYLEN scalar {Deref(I_arraylen, fst $2), snd $1} | ARRAYLEN BRACKET lines BRACKET_END {sp_0($2); Deref(I_arraylen, Block(fst $3)), snd $1}
-scalar: SCALAR_IDENT {Deref(I_scalar , to_Ident $1), snd $1} | DOLLAR scalar {Deref(I_scalar , fst $2), snd $1} | DOLLAR BRACKET lines BRACKET_END {sp_0($2); Deref(I_scalar , Block(fst $3)), snd $1} | DOLLAR BRACKET BRACKET expr BRACKET_END BRACKET_END {sp_0($2); sp_0($3); sp_p($5); sp_0($6); Deref(I_scalar, Ref(I_hash, fst $4)), snd $1}
-func: FUNC_IDENT {Deref(I_func , to_Ident $1), snd $1} | AMPERSAND scalar {Deref(I_func , fst $2), snd $1} | AMPERSAND BRACKET lines BRACKET_END {sp_0($2); Deref(I_func , Block(fst $3)), snd $1}
-array: ARRAY_IDENT {Deref(I_array , to_Ident $1), snd $1} | AT scalar {Deref(I_array , fst $2), snd $1} | AT BRACKET lines BRACKET_END {sp_0($2); Deref(I_array , Block(fst $3)), snd $1}
-hash: HASH_IDENT {Deref(I_hash , to_Ident $1), snd $1} | PERCENT scalar {Deref(I_hash , fst $2), snd $1} | PERCENT BRACKET lines BRACKET_END {sp_0($2); Deref(I_hash , Block(fst $3)), snd $1}
-star: STAR_IDENT {Deref(I_star , to_Ident $1), snd $1} | STAR scalar {Deref(I_star , fst $2), snd $1} | STAR BRACKET lines BRACKET_END {sp_0($2); Deref(I_star , Block(fst $3)), snd $1}
+arraylen: ARRAYLEN_IDENT {Deref(I_arraylen, to_Ident $1), snd $1} | ARRAYLEN scalar {sp_0($2); Deref(I_arraylen, fst $2), snd $1} | ARRAYLEN BRACKET lines BRACKET_END {sp_0($2); sp_same $3 $4; Deref(I_arraylen, Block(fst $3)), snd $1}
+scalar: SCALAR_IDENT {Deref(I_scalar , to_Ident $1), snd $1} | DOLLAR scalar {sp_0($2); Deref(I_scalar , fst $2), snd $1} | DOLLAR BRACKET lines BRACKET_END {sp_0($2); sp_same $3 $4; Deref(I_scalar , Block(fst $3)), snd $1} | DOLLAR BRACKET BRACKET expr BRACKET_END BRACKET_END {sp_0($2); sp_0($3); sp_p($5); sp_0($6); Deref(I_scalar, Ref(I_hash, fst $4)), snd $1}
+func: FUNC_IDENT {Deref(I_func , to_Ident $1), snd $1} | AMPERSAND scalar {sp_0($2); Deref(I_func , fst $2), snd $1} | AMPERSAND BRACKET lines BRACKET_END {sp_0($2); sp_same $3 $4; Deref(I_func , Block(fst $3)), snd $1}
+array: ARRAY_IDENT {Deref(I_array , to_Ident $1), snd $1} | AT scalar {sp_0($2); Deref(I_array , fst $2), snd $1} | AT BRACKET lines BRACKET_END {sp_0($2); sp_same $3 $4; Deref(I_array , Block(fst $3)), snd $1}
+hash: HASH_IDENT {Deref(I_hash , to_Ident $1), snd $1} | PERCENT scalar {sp_0($2); Deref(I_hash , fst $2), snd $1} | PERCENT BRACKET lines BRACKET_END {sp_0($2); sp_same $3 $4; Deref(I_hash , Block(fst $3)), snd $1}
+star: STAR_IDENT {Deref(I_star , to_Ident $1), snd $1} | STAR scalar {sp_0($2); Deref(I_star , fst $2), snd $1} | STAR BRACKET lines BRACKET_END {sp_0($2); sp_same $3 $4; Deref(I_star , Block(fst $3)), snd $1}
expr_or_empty: {Block [], (Space_none, bpos)} | expr {$1}
diff --git a/perl_checker.src/parser_helper.ml b/perl_checker.src/parser_helper.ml
index cc91c83..9cef1f8 100644
--- a/perl_checker.src/parser_helper.ml
+++ b/perl_checker.src/parser_helper.ml
@@ -2,6 +2,22 @@ open Types
open Common
let bpos = -1, -1
+
+
+let not_complex = function
+ | Call_op("?:", _) -> false
+ | _ -> true
+
+let not_simple = function
+ | Num _ | Ident _ | Deref(_, Ident _) -> false
+ | _ -> true
+
+let string_of_Ident = function
+ | Ident(None, s, _) -> s
+ | Ident(Some fq, s, _) -> fq ^ "::" ^ s
+ | _ -> internal_error "string_of_Ident"
+
+
let msg_with_pos (start, end_) msg = Info.pos2sfull_current start end_ ^ msg
let die_with_pos raw_pos msg = failwith (msg_with_pos raw_pos msg)
let warn raw_pos msg = prerr_endline (msg_with_pos raw_pos msg)
@@ -17,6 +33,7 @@ let warn_no_space start = warn (start, start) "you should have a space here"
let warn_cr start = warn (start, start) "you should not have a carriage-return (\\n) here"
let warn_space start = warn (start, start) "you should not have a space here"
+
let sp_0(_, (spaces, (start, _))) =
match spaces with
| Space_none -> ()
@@ -65,14 +82,23 @@ let sp_cr(_, (spaces, (start, _))) =
| Space_n -> warn (start, start) "you should have a carriage-return (\\n) here"
| Space_cr -> ()
-let not_complex = function
- | Call_op("?:", _) -> false
- | _ -> true
+let sp_same (_, (spaces1, _) as ter1) (_, (spaces2, _) as ter2) =
+ if spaces1 <> Space_0 then sp_p ter2
+ else if spaces2 <> Space_0 then sp_p ter1
-let string_of_Ident = function
- | Ident(None, s, _) -> s
- | Ident(Some fq, s, _) -> fq ^ "::" ^ s
- | _ -> internal_error "string_of_Ident"
+let op s (_, both) = ((), both), s
+let op_p s e = sp_p e ; op s e
+
+let call_op((prev_ter, op), ter, para) =
+ sp_same prev_ter ter ;
+ Call_op(op, para)
+
+let check_lines_after_BRACKET (l, both) =
+ (match l with Semi_colon :: _ -> sp_0 | _ -> sp_p)(l, both)
+
+let check_word_alone (word, _) =
+ if string_of_Ident word = "time" then die_rule "please use time() instead of time";
+ word
let check_parenthesized_first_argexpr word (e, (_, (start, _)) as ex) =
let want_space = word.[0] = '-' in
@@ -82,7 +108,9 @@ let check_parenthesized_first_argexpr word (e, (_, (start, _)) as ex) =
if l = [] then sp_n(ex) else die_with_pos (start, start) "can't handle this nicely"
else
if l = [] then sp_0(ex) else die_with_pos (start, start) "you must not have a space here"
- | _ -> sp_p(ex)
+ | _ ->
+ if word = "time" then die_rule "please use time() instead of time";
+ sp_p(ex)
let check_foreach (s, (_, pos)) = if s = "for" then warn pos "write \"foreach\" instead of \"for\""
let check_for (s, (_, pos)) = if s = "foreach" then warn pos "write \"for\" instead of \"foreach\""
diff --git a/perl_checker.src/parser_helper.mli b/perl_checker.src/parser_helper.mli
index 5d1c47b..304f592 100644
--- a/perl_checker.src/parser_helper.mli
+++ b/perl_checker.src/parser_helper.mli
@@ -1,4 +1,7 @@
val bpos : int * int
+val not_complex : Types.fromparser -> bool
+val not_simple : Types.fromparser -> bool
+val string_of_Ident : Types.fromparser -> string
val msg_with_pos : int * int -> string -> string
val die_with_pos : int * int -> string -> 'a
val warn : int * int -> string -> unit
@@ -16,8 +19,21 @@ val sp_1 : 'a * (Types.spaces * (int * 'b)) -> unit
val sp_n : 'a * (Types.spaces * (int * 'b)) -> unit
val sp_p : 'a * (Types.spaces * (int * 'b)) -> unit
val sp_cr : 'a * (Types.spaces * (int * 'b)) -> unit
-val not_complex : Types.fromparser -> bool
-val string_of_Ident : Types.fromparser -> string
+val sp_same :
+ 'a * (Types.spaces * (int * 'b)) ->
+ 'c * (Types.spaces * (int * 'd)) -> unit
+val op : 'a -> 'b * 'c -> (unit * 'c) * 'a
+val op_p :
+ 'a ->
+ 'b * (Types.spaces * (int * 'c)) ->
+ (unit * (Types.spaces * (int * 'c))) * 'a
+val call_op :
+ (('a * (Types.spaces * (int * 'b))) * string) *
+ ('c * (Types.spaces * (int * 'd))) * Types.fromparser list ->
+ Types.fromparser
+val check_lines_after_BRACKET :
+ Types.fromparser list * (Types.spaces * (int * 'a)) -> unit
+val check_word_alone : Types.fromparser * 'a -> Types.fromparser
val check_parenthesized_first_argexpr :
string -> Types.fromparser list * (Types.spaces * (int * 'a)) -> unit
val check_foreach : string * ('a * (int * int)) -> unit
diff --git a/perl_checker.src/types.mli b/perl_checker.src/types.mli
index 5567eb9..b53ed0e 100644
--- a/perl_checker.src/types.mli
+++ b/perl_checker.src/types.mli
@@ -42,3 +42,4 @@ type fromparser =
| Label of string
| Too_complex
+ | Semi_colon