operator_precendece.pl 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/usr/bin/perl
  2. # Experimental operator-precedence support
  3. # 1. Rename the sub "parse_obj" to "parse_group" inside the parser.
  4. # 2. Copy-pase this code inside the parser.
  5. sub level_0 {
  6. my ($self, %opt) = @_;
  7. (($self->parse_whitespace(code => $opt{code}))[1] || /\G(?=;|->)/) && return $opt{obj};
  8. local *_ = $opt{code};
  9. my %struct = (
  10. $self->{class} => [
  11. {
  12. self => $opt{obj}
  13. }
  14. ]
  15. );
  16. if (/\G(\*\*)/gc) {
  17. my $operator = $1;
  18. my $obj = $self->parse_group(code => $opt{code});
  19. push @{$struct{$self->{class}}[-1]{call}},
  20. {method => $operator, arg => [$self->level_0(obj => $obj, code => $opt{code}) // $obj]};
  21. return \%struct;
  22. }
  23. return;
  24. }
  25. sub level_1 {
  26. my ($self, %opt) = @_;
  27. (($self->parse_whitespace(code => $opt{code}))[1] || /\G(?=;|->)/) && return $opt{obj};
  28. local *_ = $opt{code};
  29. my %struct = (
  30. $self->{class} => [
  31. {
  32. self => $opt{obj}
  33. }
  34. ]
  35. );
  36. my $match;
  37. while (/\G(\*|\/)/gc) {
  38. my $operator = $1;
  39. my $obj = $self->parse_group(code => $opt{code});
  40. push @{$struct{$self->{class}}[-1]{call}},
  41. {method => $operator, arg => [$self->level_0(obj => $obj, code => $opt{code}) // $obj]};
  42. $match //= 1;
  43. }
  44. $match ? \%struct : undef;
  45. }
  46. sub level_2 {
  47. my ($self, %opt) = @_;
  48. (($self->parse_whitespace(code => $opt{code}))[1] || /\G(?=;|->)/) && return $opt{obj};
  49. local *_ = $opt{code};
  50. my %struct = (
  51. $self->{class} => [
  52. {
  53. self => $opt{obj}
  54. }
  55. ]
  56. );
  57. my $match;
  58. while (/\G(\+|-)/gc) {
  59. my $operator = $1;
  60. my $obj = $self->parse_group(code => $opt{code});
  61. push @{$struct{$self->{class}}[-1]{call}},
  62. {
  63. method => $operator,
  64. arg => [$self->level_0(obj => $obj, code => $opt{code}) // $self->level_1(obj => $obj, code => $opt{code}) // $obj]
  65. };
  66. $match //= 1;
  67. }
  68. $match ? \%struct : undef;
  69. }
  70. sub parse_obj {
  71. my ($self, %opt) = @_;
  72. my $obj = $self->parse_group(code => $opt{code}) // return;
  73. local *_ = $opt{code};
  74. (($self->parse_whitespace(code => $opt{code}))[1] || /\G(?=;|->)/) && return $obj;
  75. return ($self->level_0(obj => $obj, code => $opt{code}) // $self->level_1(obj => $obj, code => $opt{code})
  76. // $self->level_2(obj => $obj, code => $opt{code}) // $obj);
  77. return $obj;
  78. }
  79. __END__
  80. say (2 + 2 ** 3 + 2); # 12
  81. say (2 ** 3 + 2); # 10
  82. say (2 + 2 * 3 + 2); # 10
  83. say (2 ** 3 ** 4 * 2); # 4835703278458516698824704
  84. say (2 + 4 - 1); # 5
  85. say (4 * 3 / 2); # 6
  86. say (4 / 3 * 2); # 2.66666
  87. say (12 / 4 * 2); # 6
  88. say (12 + 3 * 2); # 18
  89. say (1+2 * 3+4); # 21 or 11
  90. say (1 + ++2); # 4