File Coverage

blib/lib/Language/FormulaEngine/Parser.pm
Criterion Covered Total %
statement 216 224 96.4
branch 71 80 88.7
condition 26 32 81.2
subroutine 48 50 96.0
pod 25 25 100.0
total 386 411 93.9


line stmt bran cond sub pod time code
1             package Language::FormulaEngine::Parser;
2 7     7   454456 use Moo;
  7         22988  
  7         43  
3 7     7   4495 use Carp;
  7         16  
  7         442  
4 7     7   1046 use Try::Tiny;
  7         2675  
  7         384  
5 7     7   45 use List::Util qw( min max );
  7         23  
  7         468  
6             use Language::FormulaEngine::Parser::ContextUtil
7 7     7   3114 qw( calc_text_coordinates format_context_string format_context_multiline );
  7         18  
  7         433  
8 7     7   1492 use namespace::clean;
  7         29065  
  7         43  
9              
10             # ABSTRACT: Create parse tree from an input string
11             our $VERSION = '0.04'; # VERSION
12              
13              
14             has parse_tree => ( is => 'rw' );
15             has error => ( is => 'rw' );
16             has functions => ( is => 'rw' );
17             has symbols => ( is => 'rw' );
18              
19             sub parse {
20 271     271 1 44755 my ($self, $input)= @_;
21 271         740 $self->reset;
22 271         459 $self->{input}= $input;
23 271         728 pos( $self->{input} )= 0;
24             try {
25 271     271   9294 $self->next_token;
26 270         519 my $tree= $self->parse_expr;
27             # It is an error if there was un-processed input.
28 269 100       500 $self->token_type eq '0'
29             or die sprintf('Unexpected %s "%s" near %s',
30             $self->token_type, $self->token_value, $self->token_context);
31 268         729 $self->parse_tree($tree);
32             } catch {
33 3     3   46 chomp;
34 3         16 $self->error($_);
35 271         1493 };
36 271         4465 return $self->parse_tree;
37             }
38              
39             sub reset {
40 271     271 1 379 my $self= shift;
41 271         972 $self->parse_tree(undef);
42 271         459 $self->error(undef);
43 271         642 $self->functions({});
44 271         513 $self->symbols({});
45 271         406 delete @{$self}{'input','token_type','token_value','token_pos'};
  271         854  
46 271         400 $self;
47             }
48              
49              
50             sub deparse {
51 39     39 1 3441 my ($self, $node)= @_;
52 39 100       86 $node= $self->parse_tree unless @_ > 1;
53 39         88 $node->deparse($self);
54             }
55              
56              
57 0     0 1 0 sub input { shift->{input} }
58 0     0 1 0 sub input_pos { pos( shift->{input} ) }
59 326     326 1 1007 sub token_type { shift->{token_type} }
60 47     47 1 221 sub token_value { shift->{token_value} }
61 46     46 1 101 sub token_pos { shift->{token_pos} }
62              
63              
64             sub next_token {
65 1997     1997 1 47023 my $self= shift;
66            
67             # If already reached end of input, throw an exception.
68             die "Can't call next_token after end of input"
69 1997 50 100     4484 if '0' eq ($self->{token_type}||'');
70            
71             # Detect the next token
72 1997         3271 my ($type, $val, $pos0, $pos1)= ('','');
73 1997         3159 while ($type eq '') {
74 2204   100     3965 $pos0= pos($self->{input}) || 0;
75 2204         43772 ($type, $val)= $self->scan_token;
76 2204   100     10750 $pos1= pos($self->{input}) || 0;
77             # Check for end of buffer, even if it matched.
78 2204 100       3799 if ($pos1 >= length $self->{input}) {
79             #pos($self->{input})= $pos0; # rewind to start of token before growing buffer
80             #if ($self->_grow_buffer) {
81             # $log->trace("grow buffer succeeded");
82             # $type= '';
83             # next;
84             #}
85             #pos($self->{input})= $pos1; # restore actual position\
86             # If we didn't get a token or are ignoring this final token, then return the EOF token
87 553 100 100     1395 if (!defined $type || $type eq '') {
88 279         414 $type= 0;
89 279         360 $val= '';
90 279         337 $pos0= $pos1;
91 279         382 last;
92             }
93             }
94 1925 100       3037 defined $type
95             or die "Unknown syntax at ".$self->token_context."\n";
96 1924 50       4182 $pos1 > $pos0
97             or croak "Tokenizer consumed zero characters";
98             }
99 1996         2650 @{$self}{'token_type','token_value','token_pos'}= ($type,$val,$pos0);
  1996         3730  
100 1996         2984 return $type, $val;
101             }
102              
103              
104             sub consume_token {
105 929     929 1 18282 my $self= shift;
106             croak "Can't consume EOF"
107 929 100       2502 if $self->{token_type} eq '0';
108 919         1239 my $val= $self->{token_value};
109 919         1817 $self->next_token;
110 919         1751 return $val;
111             }
112              
113             sub token_context {
114 2     2 1 7 my ($self, %args)= @_;
115             return format_context_multiline($self->{input}, $self->{token_pos}||0, pos($self->{input})||0, \%args)
116 2 50 0     6 if delete $args{multiline};
      0        
117 2   100     17 return format_context_string($self->{input}, $self->{token_pos}||0, pos($self->{input})||0);
      100        
118             }
119              
120              
121 715     715 1 1246 sub parse_expr { shift->parse_or_expr; }
122              
123             sub parse_or_expr {
124 715     715 1 930 my $self= shift;
125 715         1082 my $first= $self->parse_and_expr;
126 714 50       1696 return $first unless $self->{token_type} eq 'or';
127 0         0 my @or_expr= $first;
128 0         0 while ($self->{token_type} eq 'or') {
129 0         0 $self->next_token;
130 0         0 push @or_expr, $self->parse_and_expr;
131             }
132 0         0 return $self->new_call('or', \@or_expr);
133             }
134              
135             sub parse_and_expr {
136 715     715 1 904 my $self= shift;
137 715         1184 my $first= $self->parse_not_expr;
138 714 100       1401 return $first unless $self->{token_type} eq 'and';
139 7         14 my @and_expr= $first;
140 7         18 while ($self->{token_type} eq 'and') {
141 7         17 $self->next_token;
142 7         14 push @and_expr, $self->parse_not_expr;
143             }
144 7         16 return $self->new_call('and', \@and_expr);
145             }
146              
147             sub parse_not_expr {
148 722     722 1 932 my $self= shift;
149 722 100 66     2217 if ($self->{token_type} eq 'not' or $self->{token_type} eq '!') {
150 5         13 $self->next_token;
151 5         12 return $self->new_call('not', [ $self->parse_cmp_expr ]);
152             }
153 717         1182 return $self->parse_cmp_expr;
154             }
155              
156             my %_cmp_ops= map { $_ => 1 } qw( > < >= <= != == );
157             sub parse_cmp_expr {
158 722     722 1 897 my $self= shift;
159 722         1164 my $first= $self->parse_sum_expr;
160 721 100       1739 return $first unless $_cmp_ops{$self->{token_type}};
161 23         49 my @expr= $first;
162 23         58 while ($_cmp_ops{$self->{token_type}}) {
163 31         66 push @expr, $self->new_string($self->{token_type});
164 31         83 $self->next_token;
165 31         70 push @expr, $self->parse_sum_expr;
166             }
167 23         56 return $self->new_call('compare', \@expr);
168             }
169              
170             sub parse_sum_expr {
171 753     753 1 893 my $self= shift;
172 753         1186 my $first= $self->parse_prod_expr;
173 752 100 100     2211 return $first unless $self->{token_type} eq '+' or $self->{token_type} eq '-';
174 24         52 my @sum_expr= $first;
175 24   100     125 while ($self->{token_type} eq '+' or $self->{token_type} eq '-') {
176 31         71 my $negate= $self->consume_token eq '-';
177 31         73 my $operand= $self->parse_prod_expr;
178 31 100       125 push @sum_expr, $negate? $self->get_negative($operand) : $operand;
179             }
180 24         54 return $self->new_call('sum', \@sum_expr);
181             }
182              
183             sub parse_prod_expr {
184 784     784 1 947 my $self= shift;
185 784         1272 my $value= $self->parse_unit_expr;
186 783   100     2550 while ($self->{token_type} eq '*' or $self->{token_type} eq '/') {
187 35         68 my $op= $self->consume_token;
188 35         73 my $right= $self->parse_unit_expr;
189 35 100       109 $value= $self->new_call( $op eq '*'? 'mul' : 'div', [ $value, $right ] );
190             }
191 783         1170 return $value;
192             }
193              
194             sub parse_unit_expr {
195 849     849 1 1032 my $self= shift;
196 849         1020 my $negate= 0;
197 849         983 my $expr;
198              
199 849 100       1400 if ($self->{token_type} eq '-') {
200 30         56 $self->next_token;
201 30         71 return $self->get_negative($self->parse_unit_expr);
202             }
203              
204 819 100       1315 if ($self->{token_type} eq '(') {
205 11         27 $self->next_token;
206 11         31 my $args= $self->parse_list;
207             die "Expected ')' near ".$self->token_context."\n"
208 11 50       25 if $self->{token_type} ne ')';
209 11         25 $self->next_token;
210 11 100       37 return @$args > 1? $self->new_call('list', $args) : $args->[0];
211             }
212            
213 808 100       1282 if ($self->{token_type} eq 'Number') {
214 313         497 return $self->new_number($self->consume_token);
215             }
216            
217 495 100       807 if ($self->{token_type} eq 'String') {
218 84         149 return $self->new_string($self->consume_token);
219             }
220            
221 411 100       699 if ($self->{token_type} eq 'Identifier') {
222 410         600 my $id= $self->consume_token;
223 410 100       818 if ($self->{token_type} eq '(') {
224 259         570 $self->next_token;
225 259 100       639 my $args= $self->{token_type} eq ')'? [] : $self->parse_list;
226             die "Expected ')' near ".$self->token_context."\n"
227 259 50       489 if $self->{token_type} ne ')';
228 259         503 $self->next_token;
229 259         527 return $self->new_call($id, $args);
230             }
231             else {
232 151         350 return $self->new_symbol($id);
233             }
234             }
235            
236 1 50       5 if ($self->{token_type} eq '0') {
237 1         9 die "Expected expression component near (end of input)";
238             }
239            
240 0         0 die "Unexpected token $self->{token_type} '$self->{token_value}' near ".$self->token_context."\n";
241             }
242              
243             sub parse_list {
244 261     261 1 358 my $self= shift;
245 261         489 my @args= $self->parse_expr;
246 261         504 while ($self->{token_type} eq ',') {
247 184         373 $self->next_token;
248 184         386 push @args, $self->parse_expr;
249             }
250 261         439 return \@args;
251             }
252              
253              
254             our (@CMP_OPS, @MATH_OPS, @LOGIC_OPS, @LIST_OPS);
255             BEGIN {
256 7     7   42 @CMP_OPS= (qw( = == != <> > >= < <= ), "\x{2260}", "\x{2264}", "\x{2265}");
257 7         68 @MATH_OPS= qw( + - * / );
258 7         20 @LOGIC_OPS= qw( and or not ! );
259 7         14 @LIST_OPS= ( ',', '(', ')' );
260             my %keywords= (
261 7         26 (map { $_ => $_ } @CMP_OPS, @MATH_OPS, @LOGIC_OPS, @LIST_OPS),
  154         368  
262             '=' => '==', '<>' => '!=', "\x{2260}" => '!=',
263             "\x{2264}" => '<=', "\x{2265}" => '>=',
264             );
265 154         274 my $kw_regex= join '|', map { "\Q$_\E" }
266 7         64 sort { length($b) <=> length($a) } # longest keywords get priority
  464         630  
267             keys %keywords;
268            
269             # Evaling this just to make sure the regex gets compiled one single time
270 7 50   2204   3810 my $scan_token= eval q%
  2204 100       4195  
  2204 100       5411  
  210 100       604  
  1994 100       4888  
  318 100       1272  
  1676 100       3046  
  2 100       12  
  1674 100       3608  
  889 100       3456  
  785         1737  
  421         1491  
  364         979  
  87         285  
  87         222  
  87         205  
  87         267  
  277         585  
271             sub {
272             my $self= shift;
273            
274             # Ignore whitespace
275             if ($self->{input} =~ /\G(\s+)/gc) {
276             return '' => ''; # empty string causes next_token to loop
277             }
278            
279             # Check for numbers
280             if ($self->{input} =~ /\G([0-9]*\.?[0-9]+(?:[eE][+-]?[0-9]+)?)\b/gc) {
281             return Number => $1+0;
282             }
283             # or hex numbers
284             if ($self->{input} =~ /\G0x([0-9A-Fa-f]+)/gc) {
285             return Number => hex($1);
286             }
287            
288             # Check for any keyword, and convert the type to the canonical (lowercase) name.
289             if ($self->{input} =~ /\G(%.$kw_regex.q%)/gc) {
290             return $keywords{lc $1} => $1;
291             }
292            
293             # Check for identifiers
294             if ($self->{input} =~ /\G([A-Za-z_][A-Za-z0-9_.]*)\b/gc) {
295             return Identifier => $1;
296             }
297            
298             # Single or double quoted string, using Pascal-style repeated quotes for escaping
299             if ($self->{input} =~ /\G(?:"((?:[^"]|"")*)"|'((?:[^']|'')*)')/gc) {
300             my $str= defined $1? $1 : $2;
301             $str =~ s/""/"/g if defined $1;
302             $str =~ s/''/'/g if defined $2;
303             return String => $str;
304             }
305             return;
306             }
307             % or die $@;
308 7     7   16266 no strict 'refs';
  7         18  
  7         317  
309 7         4732 *scan_token= $scan_token;
310             }
311              
312              
313 359     359   791 sub Language::FormulaEngine::Parser::Node::Call::function_name { $_[0][0] }
314 377     377   1075 sub Language::FormulaEngine::Parser::Node::Call::parameters { $_[0][1] }
315             sub Language::FormulaEngine::Parser::Node::Call::evaluate {
316 164     164   1100 my ($self, $namespace)= @_;
317 164         442 $namespace->evaluate_call($self);
318             }
319             sub Language::FormulaEngine::Parser::Node::Call::deparse {
320 12     12   22 my ($node, $parser)= @_;
321             return $node->function_name . (
322 12         47 !@{$node->parameters}? '()'
323 12 100       25 : '( ' .join(', ', map $parser->deparse($_), @{$node->parameters}). ' )'
  11         20  
324             )
325             }
326              
327             sub new_call {
328 360     360 1 635 my ($self, $fn, $params)= @_;
329 360         964 $self->functions->{$fn}++; # record dependency on this function
330 360         1199 bless [ $fn, $params ], 'Language::FormulaEngine::Parser::Node::Call';
331             }
332              
333              
334 88     88   117 sub Language::FormulaEngine::Parser::Node::Symbol::symbol_name { ${$_[0]} }
  88         251  
335             sub Language::FormulaEngine::Parser::Node::Symbol::evaluate {
336 62     62   95 my ($self, $namespace)= @_;
337 62         144 $namespace->get_value($$self);
338             }
339             sub Language::FormulaEngine::Parser::Node::Symbol::deparse {
340 14     14   32 shift->symbol_name;
341             }
342              
343             sub new_symbol {
344 151     151 1 255 my ($self, $name)= @_;
345 151         393 $self->symbols->{$name}++; # record dependency on this variable
346 151         401 bless \$name, 'Language::FormulaEngine::Parser::Node::Symbol';
347             }
348              
349              
350 62     62   77 sub Language::FormulaEngine::Parser::Node::String::string_value { ${$_[0]} }
  62         171  
351 51     51   67 sub Language::FormulaEngine::Parser::Node::String::evaluate { ${$_[0]} }
  51         165  
352             sub _str_escape {
353 6     6   13 my $str= shift;
354 6         11 $str =~ s/'/''/g;
355 6         23 "'$str'";
356             }
357             sub Language::FormulaEngine::Parser::Node::String::deparse {
358 6     6   12 _str_escape(shift->string_value);
359             }
360              
361             sub new_string {
362 115     115 1 214 my ($self, $text)= @_;
363 115         293 bless \$text, 'Language::FormulaEngine::Parser::Node::String'
364             }
365              
366              
367 200     200   242 sub Language::FormulaEngine::Parser::Node::Number::number_value { ${$_[0]} }
  200         1005  
368 140     140   189 sub Language::FormulaEngine::Parser::Node::Number::evaluate { ${$_[0]} }
  140         390  
369 7     7   15 sub Language::FormulaEngine::Parser::Node::Number::deparse { shift->number_value }
370              
371             sub new_number {
372 348     348 1 513 my $value= $_[1]+0;
373 348         918 bless \$value, 'Language::FormulaEngine::Parser::Node::Number'
374             }
375              
376              
377             sub get_negative {
378 40     40 1 79 my ($self, $node)= @_;
379 40 100       172 return $self->new_number(-$node->number_value) if $node->can('number_value');
380 5 50 66     24 return $node->parameters->[0] if $node->can('function_name') and $node->function_name eq 'negative';
381 5         16 return $self->new_call('negative', [$node]);
382             }
383              
384             1;
385              
386             __END__
387              
388             =pod
389              
390             =encoding UTF-8
391              
392             =head1 NAME
393              
394             Language::FormulaEngine::Parser - Create parse tree from an input string
395              
396             =head1 VERSION
397              
398             version 0.04
399              
400             =head1 SYNOPSIS
401              
402             my $parse_tree= Language::FormulaEngine::Parser->new->parse($string);
403              
404             =head1 DESCRIPTION
405              
406             This class scans tokens from an input string and builds a parse tree. In compiler terminology,
407             it is both a Scanner and Parser. It performs a top-down recursive descent parse, because this
408             is easy and gives good error messages. It only parses strings, but leaves room for subclasses
409             to implement streaming. By default, the parser simply applies a Grammar to the input, without
410             checking whether the functions variables exist, but can be subclassed to do more detailed
411             analysis during the parse.
412              
413             The generated parse tree is made up of Function nodes (each infix operator is converted to a
414             named function) and each Function node may contain Symbols, Strings, Numbers, and other
415             Function nodes. The parse tree can be passed to the Evaluator for instant execution, or passed
416             to the Compiler to generate an optimized perl coderef. The parse tree is lightweight, and does
417             not include token/context information; this could also be added by a subclass.
418              
419             =head1 PUBLIC API
420              
421             =head2 parse
422              
423             Parse a new input text, updating all derived attributes with the result of the operation.
424             It returns the value of L</parse_tree> (which is undef if the parse failed).
425             On failure, the exception is stored in L</error> and other attributes like L</token_pos> may
426             contain useful diagnostic information.
427              
428             =head2 parse_tree
429              
430             This holds the generated parse tree, or C<undef> if the parse failed. See L</"Parse Nodes">.
431              
432             =head2 error
433              
434             This is C<undef> if the parse succeeded, else an error message describing the syntax that ended
435             the parse.
436              
437             =head2 functions
438              
439             A set (hashref) of all function names encountered during the parse.
440              
441             =head2 symbols
442              
443             A set (hashref) of all non-function symbols encountered. (variables, constnts, etc.)
444              
445             =head2 reset
446              
447             Clear the results of the previous parse, to re-use the object. Returns C<$self> for chaining.
448              
449             =head2 deparse
450              
451             my $formula_text= $parser->deparse($tree);
452              
453             Return a canonical formula text for the parse tree, or a parse tree that you supply.
454              
455             =head1 EXTENSIBLE API
456              
457             These methods and attributes are documented for purposes of subclassing the parser.
458              
459             =head2 input
460              
461             The input string being scanned.
462             Code within the parser should access this as C<< $self->{input} >> for efficiency.
463              
464             =head2 input_pos
465              
466             Shortcut for C<< pos($self->{input}) >>.
467              
468             =head2 token_type
469              
470             Type of current token scanned from C<input>.
471             Code within the parser should access this as C<< $self->{token_type} >> for efficiency.
472              
473             =head2 token_value
474              
475             Value of current token scanned from C<input>, with escape sequences and etc resolved to a
476             sensible perl value.
477             Code within the parser should access this as C<< $self->{token_value} >> for efficiency.
478              
479             =head2 token_pos
480              
481             An offset within C<input> where this token started.
482             Code within the parser should access this as C<< $self->{token_pos} >> for efficiency.
483              
484             =head2 next_token
485              
486             Advance to the next token, replacing the values of C<token_> variables and updating
487             C<input_pos>. Returns the token_type, of which all are true except EOF which has a
488             type of C<0>, so this also means the function returns true if it parsed a token and
489             false if it reached EOF. It dies if no token could be parsed.
490             If you call next_token again after the eof token, it throws an exception.
491              
492             This method is a wrapper around L</scan_token>. Override that method to add new token types.
493              
494             =head2 scan_token
495              
496             Pattern-match the next token, and either return C<< $type => $value >> or an empty list if
497             the syntax is invalid. This is intended to be overridden by subclasses.
498              
499             =head2 consume_token
500              
501             return $self->consume_token if $self->{token_type} eq $desired_type;
502              
503             This is a shorthand for returning the current C<token_value> while also calling C<next_token>.
504              
505             =head2 token_context
506              
507             my $text= $self->token_context(%options);
508              
509             Default behavior generates a string like:
510              
511             "'blah blah' on line 15, char 12"
512              
513             Passing C<< token_context(multiline => 1) >> generates a string like
514              
515             "Expected something else at line 15, char 16\n" .
516             "blah blah blah token blah blah\n" .
517             " ^^^^^\n"
518              
519             Multiline additionally takes arguments as described in
520             L<Language::FormulaEngine::Parser::ContextUtil/format_context_multiline>.
521              
522             =head1 GRAMMAR
523              
524             =head2 Parse Rules
525              
526             The default grammar implements the following rules:
527              
528             expr ::= or_expr
529             or_expr ::= and_expr ( 'or' and_expr )*
530             and_expr ::= not_expr ( 'and' not_expr )*
531             not_expr ::= ( 'not' | '!' ) cmp_expr | cmp_expr
532             cmp_expr ::= sum_expr ( ( '=' | '==' | '<>' | '\u2260' | '<' | '<=' | '>' | '>=' ) sum_expr )*
533             sum_expr ::= prod_expr ( ('+' | '-') prod_expr )*
534             prod_expr ::= ( unit_expr ('*' | '/') )* unit_expr
535             unit_expr ::= '-' unit_expr | Identifier '(' list ')' | '(' (expr|list) ')' | Identifier | Number | String
536             list ::= expr ( ',' expr )* ','?
537              
538             C<ident>, C<num>, C<str>, and all the punctuation symbols are tokens.
539              
540             The parser uses a Recursive Descent algorithm implemented as the following method calls.
541             Each method consumes tokens from C<< $self >> and return a L</"PARSE NODES">:
542              
543             =over
544              
545             =item parse_expr
546              
547             =item parse_or_expr
548              
549             =item parse_and_expr
550              
551             =item parse_not_expr
552              
553             =item parse_cmp_expr
554              
555             =item parse_sum_expr
556              
557             =item parse_prod_expr
558              
559             =item parse_unit_expr
560              
561             =item parse_list
562              
563             =back
564              
565             =head2 Token Types
566              
567             =over
568              
569             =item C<'Number'>
570              
571             All the common decimal representations of integers and floating point numbers
572             which perl can parse. Optional decimals and decimal point followed by decimals
573             and optional exponent, ending at either the end of the input or a non-alphanumeric.
574              
575             =item C<'String'>
576              
577             A single-quoted or double-quoted string, treating a double occurrence of the quote
578             character to mean a literal quote character. ("Pascal style")
579              
580             'apostrophes are''nt hard'
581              
582             There are no escape sequences though, so to get control characters or awkward unicode
583             into a string you need something like:
584              
585             concat("smile ",char(0x263A))
586              
587             which depends on those functions being available in the namespace.
588              
589             =item Keywords...
590              
591             Keywords include the "word" tokens like 'OR', but also every text literal seen in a parse rule
592             such as operators and punctuation.
593             The C<token_type> of the keyword is the canonical version of the keyword, and the C<token_value>
594             is the actual text that was captured. The pattern matches the longest keyword possible.
595              
596             =item C<'Identifier'>
597              
598             Any alpha (or underscore) followed by any run of alphanumerics,
599             (including underscore and period).
600              
601             =back
602              
603             =head2 Parse Nodes
604              
605             The parse tree takes a minimalist approach to node classification. In this default
606             implementation, number values, string values, and symbolic references have just a simple
607             wrapper around the value, and function calls are just a pair of function name and list of
608             arguments. All language operators are represented as function calls.
609              
610             A blessed node only needs to support one method: C<< ->evaluate($namespace) >>.
611              
612             The class name of the blessed nodes should be ignored. A function is anything which
613             C<< can("function_name") >>, a string is anything which C<< can("string_value") >>, a number is
614             anything which C<< can("number_value") >> and a symbolic reference is anything which
615             C<< can("symbolic_name") >>.
616              
617             Subclasses of Parser should implemnt new node types as needed. You probable also need to
618             update L</deparse>.
619              
620             The parser rules (C<parse_X_expr> methods) create nodes by the following methods on the Parser
621             class, so that you can easily subclass C<Parser> and override which class of node is getting
622             created.
623              
624             =over
625              
626             =item new_call
627              
628             $node= $parser->new_call( $function_name, $parameters );
629              
630             Generate a node for a function call. The returned node has attributes C<function_name>
631             and C<parameters>
632              
633             =item new_symbol
634              
635             $node= $parser->new_symbol($symbol_name);
636              
637             A reference to a symbolic value (i.e. variable or constant).
638             It has one attribute C<symbol_name>.
639              
640             =item new_string
641              
642             $node= $parser->new_string($string_value);
643              
644             A string literal. It has an attribute C<string_value> holding the raw value.
645              
646             =item new_number
647              
648             $plain_scalar= $parser->new_number($value);
649              
650             A numeric constant. It has an attribute C<number_value> holding the raw value.
651              
652             =item get_negative
653              
654             $negative_node= $parser->get_negative( $node );
655              
656             Utility method to get the "opposite of" a parse node. By default, this wraps it with the
657             function C<'negative'>, unless it already was that function then it unwraps the parameter.
658             It performs simple negation on numbers.
659              
660             =back
661              
662             =head1 AUTHOR
663              
664             Michael Conrad <mconrad@intellitree.com>
665              
666             =head1 COPYRIGHT AND LICENSE
667              
668             This software is copyright (c) 2020 by Michael Conrad, IntelliTree Solutions llc.
669              
670             This is free software; you can redistribute it and/or modify it under
671             the same terms as the Perl 5 programming language system itself.
672              
673             =cut