line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
6
|
use Moops; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# PODNAME: MarpaX::Languages::M4::Impl::Parser |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# ABSTRACT: M4 Marpa parser |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# Expose only the base implementation of parse() method |
9
|
|
|
|
|
|
|
# required by MarpaX::Languages::M4::Role::Parser |
10
|
|
|
|
|
|
|
# |
11
|
1
|
|
|
1
|
|
89871
|
class MarpaX::Languages::M4::Impl::Parser { |
|
1
|
|
|
1
|
|
27
|
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
55
|
|
|
1
|
|
|
|
|
297
|
|
|
1
|
|
|
|
|
1505
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
1220
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
58
|
|
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
42
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
89
|
|
|
1
|
|
|
|
|
46
|
|
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
14
|
|
|
1
|
|
|
|
|
3889
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
579
|
|
|
1
|
|
|
|
|
3073
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
134
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
322
|
|
|
1
|
|
|
|
|
6373
|
|
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
549
|
|
|
1
|
|
|
|
|
2157
|
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
1058
|
|
|
1
|
|
|
|
|
2087
|
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
103021
|
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
20
|
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
88
|
|
|
1
|
|
|
|
|
6232
|
|
|
0
|
|
|
|
|
0
|
|
12
|
1
|
|
|
1
|
|
311
|
use MarpaX::Languages::M4::Impl::Parser::Actions; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
10
|
|
13
|
1
|
|
|
1
|
|
49
|
use MarpaX::Languages::M4::Type::Macro -all; |
|
1
|
|
|
|
|
45
|
|
|
1
|
|
|
|
|
6
|
|
14
|
1
|
|
|
1
|
|
812
|
use MarpaX::Languages::M4::Impl::Value; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
7
|
|
15
|
1
|
|
|
1
|
|
441
|
use Marpa::R2; # 2.103_004; |
|
1
|
|
|
|
|
104830
|
|
|
1
|
|
|
|
|
14
|
|
16
|
1
|
|
|
1
|
|
44
|
use Scalar::Util qw/readonly/; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
58
|
|
17
|
1
|
|
|
1
|
|
5
|
use Types::Common::Numeric -all; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
18
|
|
|
|
|
|
|
# |
19
|
|
|
|
|
|
|
# --nesting_limit (SHOULD) take care of that |
20
|
|
|
|
|
|
|
# |
21
|
1
|
|
|
1
|
|
5460
|
no warnings 'recursion'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
217
|
|
22
|
|
|
|
|
|
|
|
23
|
1
|
|
|
|
|
17
|
our $VERSION = '0.018'; # VERSION |
24
|
|
|
|
|
|
|
|
25
|
1
|
|
|
|
|
4
|
our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY |
26
|
|
|
|
|
|
|
|
27
|
1
|
|
|
|
|
3
|
our $BASE_GRAMMAR = q{ |
28
|
|
|
|
|
|
|
inaccessible is ok by default |
29
|
|
|
|
|
|
|
:default ::= action => ::first |
30
|
|
|
|
|
|
|
lexeme default = latm => 1 |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# |
33
|
|
|
|
|
|
|
# Note: this part of the grammar is giving ambiguity |
34
|
|
|
|
|
|
|
# but we do not mind because the effect is always |
35
|
|
|
|
|
|
|
# the same: global concatenatation |
36
|
|
|
|
|
|
|
# |
37
|
|
|
|
|
|
|
argumentsGroup ::= tokens action => createArgumentsGroup rank => 1 |
38
|
|
|
|
|
|
|
| argumentsGroup LPAREN argumentsGroup RPAREN argumentsGroup action => mergeArgumentsGroup |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
arguments ::= argumentsGroup action => firstArg |
41
|
|
|
|
|
|
|
| arguments (COMMA) argumentsGroup action => nextArg |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
tokens ::= token* action => create |
44
|
|
|
|
|
|
|
event '^token' = predicted <token> # This event is to force $r->read() to not advance its location |
45
|
|
|
|
|
|
|
event 'token$' = completed <token> |
46
|
|
|
|
|
|
|
token ::= WORD |
47
|
|
|
|
|
|
|
| macro |
48
|
|
|
|
|
|
|
| QUOTEDSTRING |
49
|
|
|
|
|
|
|
| CHARACTER |
50
|
|
|
|
|
|
|
| COMMENT |
51
|
|
|
|
|
|
|
| ANYTHING |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
macro ::= MACRO # Never lexeme_read'ed |
54
|
|
|
|
|
|
|
| MACRO_ARGS macroArguments # Ditto |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
event 'macroArguments$' = completed <macroArguments> |
57
|
|
|
|
|
|
|
macroArguments ::= (LPAREN) arguments (RPAREN) |
58
|
|
|
|
|
|
|
macroArguments ::= (NOPARAM) action => fakeOneVoidParam |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
_ANYTHING ~ [\s\S] |
61
|
|
|
|
|
|
|
_NOTHING ~ [^\s\S] |
62
|
|
|
|
|
|
|
WORD ~ _NOTHING |
63
|
|
|
|
|
|
|
MACRO ~ _NOTHING |
64
|
|
|
|
|
|
|
MACRO_ARGS ~ _NOTHING |
65
|
|
|
|
|
|
|
QUOTEDSTRING ~ _NOTHING |
66
|
|
|
|
|
|
|
CHARACTER ~ _NOTHING |
67
|
|
|
|
|
|
|
COMMENT ~ _NOTHING |
68
|
|
|
|
|
|
|
# |
69
|
|
|
|
|
|
|
# ANYTHING will automatically eat a character each time we resume the SLIF: we |
70
|
|
|
|
|
|
|
# do not want this to happen |
71
|
|
|
|
|
|
|
# |
72
|
|
|
|
|
|
|
:lexeme ~ <ANYTHING> pause => before event => '^ANYTHING' |
73
|
|
|
|
|
|
|
ANYTHING ~ _ANYTHING |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
_WS ~ [\s] |
76
|
|
|
|
|
|
|
_WS_any ~ _WS* |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
:lexeme ~ <LPAREN> priority => 1 pause => before event => '^LPAREN' |
79
|
|
|
|
|
|
|
LPAREN ~ '(' _WS_any |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
:lexeme ~ <RPAREN> priority => 1 pause => before event => '^RPAREN' |
82
|
|
|
|
|
|
|
RPAREN ~ ')' |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
:lexeme ~ <NOPARAM> priority => 1 |
85
|
|
|
|
|
|
|
NOPARAM ~ '(' _WS_any ')' |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# |
88
|
|
|
|
|
|
|
# Quote from the spec (M4 POSIX): |
89
|
|
|
|
|
|
|
# If a macro name is followed by a <left-parenthesis>, its arguments are the <comma>-separated tokens |
90
|
|
|
|
|
|
|
# between the <left-parenthesis> and the matching <right-parenthesis>. Unquoted white-space characters |
91
|
|
|
|
|
|
|
# preceding each argument shall be ignored. All other characters, including trailing white-space characters, |
92
|
|
|
|
|
|
|
# are retained. |
93
|
|
|
|
|
|
|
# <comma> characters enclosed between <left-parenthesis> and <right-parenthesis> characters do not delimit arguments. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
:lexeme ~ <COMMA> priority => 1 |
96
|
|
|
|
|
|
|
COMMA ~ ',' _WS_any |
97
|
|
|
|
|
|
|
}; |
98
|
|
|
|
|
|
|
|
99
|
1
|
|
|
|
|
2
|
our $BYTOKEN_G = do { |
100
|
|
|
|
|
|
|
my $g = Marpa::R2::Scanless::G->new( |
101
|
1
|
|
|
|
|
3
|
{ source => \do {":start ::= tokens\n$BASE_GRAMMAR"} |
|
1
|
|
|
|
|
32
|
|
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
); |
104
|
|
|
|
|
|
|
}; |
105
|
1
|
|
|
|
|
194252
|
our $BYMACROARGUMENTS_G = do { |
106
|
|
|
|
|
|
|
my $g = Marpa::R2::Scanless::G->new( |
107
|
1
|
|
|
|
|
3
|
{ source => \do {":start ::= macroArguments\n$BASE_GRAMMAR"} |
|
1
|
|
|
|
|
25
|
|
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
); |
110
|
|
|
|
|
|
|
}; |
111
|
|
|
|
|
|
|
|
112
|
0
|
|
|
|
|
0
|
BEGIN { |
113
|
|
|
|
|
|
|
# |
114
|
|
|
|
|
|
|
# Marpa internal optimisation: we do not want the closures to be rechecked every time |
115
|
|
|
|
|
|
|
# we call $r->value(). This is a static information, although determined at run-time |
116
|
|
|
|
|
|
|
# the first time $r->value() is called on a recognizer. |
117
|
|
|
|
|
|
|
# |
118
|
1
|
|
|
1
|
|
6
|
no warnings 'redefine'; |
|
1
|
|
|
0
|
|
2
|
|
|
1
|
|
|
|
|
405
|
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub Marpa::R2::Recognizer::registrations { |
121
|
2024
|
|
|
2024
|
0
|
3460
|
my $recce = shift; |
122
|
2024
|
100
|
|
|
|
4853
|
if (@_) { |
123
|
2022
|
|
|
|
|
3202
|
my $hash = shift; |
124
|
2022
|
50
|
33
|
|
|
13062
|
if (! defined($hash) || |
|
|
|
33
|
|
|
|
|
125
|
|
|
|
|
|
|
ref($hash) ne 'HASH' || |
126
|
14154
|
|
|
|
|
33500
|
grep {! exists($hash->{$_})} qw/ |
127
|
|
|
|
|
|
|
NULL_VALUES |
128
|
|
|
|
|
|
|
REGISTRATIONS |
129
|
|
|
|
|
|
|
CLOSURE_BY_SYMBOL_ID |
130
|
|
|
|
|
|
|
CLOSURE_BY_RULE_ID |
131
|
|
|
|
|
|
|
RESOLVE_PACKAGE |
132
|
|
|
|
|
|
|
RESOLVE_PACKAGE_SOURCE |
133
|
|
|
|
|
|
|
PER_PARSE_CONSTRUCTOR |
134
|
|
|
|
|
|
|
/) { |
135
|
|
|
|
|
|
|
Marpa::R2::exception( |
136
|
|
|
|
|
|
|
"Attempt to reuse registrations failed:\n", |
137
|
|
|
|
|
|
|
" Registration data is not a hash containing all necessary keys:\n", |
138
|
0
|
0
|
|
|
|
0
|
" Got : " . ((ref($hash) eq 'HASH') ? join(', ', sort keys %{$hash}) : '') . "\n", |
|
0
|
|
|
|
|
0
|
|
139
|
|
|
|
|
|
|
" Want: CLOSURE_BY_RULE_ID, CLOSURE_BY_SYMBOL_ID, NULL_VALUES, PER_PARSE_CONSTRUCTOR, REGISTRATIONS, RESOLVE_PACKAGE, RESOLVE_PACKAGE_SOURCE\n" |
140
|
|
|
|
|
|
|
); |
141
|
|
|
|
|
|
|
} |
142
|
2022
|
|
|
|
|
4179
|
$recce->[Marpa::R2::Internal::Recognizer::NULL_VALUES] = $hash->{NULL_VALUES}; |
143
|
2022
|
|
|
|
|
4052
|
$recce->[Marpa::R2::Internal::Recognizer::REGISTRATIONS] = $hash->{REGISTRATIONS}; |
144
|
2022
|
|
|
|
|
3616
|
$recce->[Marpa::R2::Internal::Recognizer::CLOSURE_BY_SYMBOL_ID] = $hash->{CLOSURE_BY_SYMBOL_ID}; |
145
|
2022
|
|
|
|
|
3447
|
$recce->[Marpa::R2::Internal::Recognizer::CLOSURE_BY_RULE_ID] = $hash->{CLOSURE_BY_RULE_ID}; |
146
|
2022
|
|
|
|
|
3475
|
$recce->[Marpa::R2::Internal::Recognizer::RESOLVE_PACKAGE] = $hash->{RESOLVE_PACKAGE}; |
147
|
2022
|
|
|
|
|
3653
|
$recce->[Marpa::R2::Internal::Recognizer::RESOLVE_PACKAGE_SOURCE] = $hash->{RESOLVE_PACKAGE_SOURCE}; |
148
|
2022
|
|
|
|
|
3566
|
$recce->[Marpa::R2::Internal::Recognizer::PER_PARSE_CONSTRUCTOR] = $hash->{PER_PARSE_CONSTRUCTOR}; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
return { |
151
|
2024
|
|
|
|
|
14835
|
NULL_VALUES => $recce->[Marpa::R2::Internal::Recognizer::NULL_VALUES], |
152
|
|
|
|
|
|
|
REGISTRATIONS => $recce->[Marpa::R2::Internal::Recognizer::REGISTRATIONS], |
153
|
|
|
|
|
|
|
CLOSURE_BY_SYMBOL_ID => $recce->[Marpa::R2::Internal::Recognizer::CLOSURE_BY_SYMBOL_ID], |
154
|
|
|
|
|
|
|
CLOSURE_BY_RULE_ID => $recce->[Marpa::R2::Internal::Recognizer::CLOSURE_BY_RULE_ID], |
155
|
|
|
|
|
|
|
RESOLVE_PACKAGE => $recce->[Marpa::R2::Internal::Recognizer::RESOLVE_PACKAGE], |
156
|
|
|
|
|
|
|
RESOLVE_PACKAGE_SOURCE => $recce->[Marpa::R2::Internal::Recognizer::RESOLVE_PACKAGE_SOURCE], |
157
|
|
|
|
|
|
|
PER_PARSE_CONSTRUCTOR => $recce->[Marpa::R2::Internal::Recognizer::PER_PARSE_CONSTRUCTOR] |
158
|
|
|
|
|
|
|
}; |
159
|
|
|
|
|
|
|
} ## end sub registrations |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub Marpa::R2::Scanless::R::registrations { |
162
|
2024
|
|
|
2024
|
|
3831
|
my $slr = shift; |
163
|
2024
|
|
|
|
|
3446
|
my $thick_g1_recce = |
164
|
|
|
|
|
|
|
$slr->[Marpa::R2::Internal::Scanless::R::THICK_G1_RECCE]; |
165
|
2024
|
|
|
|
|
6241
|
return $thick_g1_recce->registrations(@_); |
166
|
|
|
|
|
|
|
} ## end sub Marpa::R2::Scanless::R::registrations |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
1
|
|
|
|
|
67105
|
has _parse_level => ( |
171
|
|
|
|
|
|
|
is => 'rwp', |
172
|
|
|
|
|
|
|
isa => PositiveOrZeroInt, |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# trigger => 1, |
175
|
|
|
|
|
|
|
default => 0 |
176
|
|
|
|
|
|
|
); |
177
|
|
|
|
|
|
|
|
178
|
1
|
0
|
|
1
|
|
2848
|
method _trigger__parse_level (PositiveOrZeroInt $parse_level, @rest) { |
|
1
|
0
|
|
1
|
|
2
|
|
|
1
|
0
|
|
0
|
|
127
|
|
|
1
|
0
|
|
|
|
6
|
|
|
1
|
0
|
|
|
|
2
|
|
|
1
|
0
|
|
|
|
138
|
|
|
1
|
|
|
|
|
1955
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
179
|
|
|
|
|
|
|
# |
180
|
|
|
|
|
|
|
# GNU testing of nesting_limit is another implementation, this |
181
|
|
|
|
|
|
|
# has no meaning for us. So, even if supported, this option does |
182
|
|
|
|
|
|
|
# nothing: the trigger is NOT enabled. |
183
|
|
|
|
|
|
|
# |
184
|
0
|
|
|
|
|
0
|
my $nesting_limit = $self->impl_nestingLimit; |
185
|
0
|
0
|
0
|
|
|
0
|
if ( $nesting_limit > 0 && $parse_level > $nesting_limit ) { |
186
|
0
|
|
|
|
|
0
|
$self->impl_raiseException( |
187
|
|
|
|
|
|
|
sprintf( 'Nesting limit of %d exceeded', $nesting_limit ) ); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
1
|
50
|
|
1
|
|
2157
|
method parser_parse (Str $input --> Str) { |
|
1
|
50
|
|
1
|
|
3
|
|
|
1
|
50
|
|
164
|
|
122
|
|
|
1
|
50
|
|
|
|
5
|
|
|
1
|
50
|
|
|
|
2
|
|
|
1
|
|
|
|
|
84
|
|
|
1
|
|
|
|
|
234
|
|
|
164
|
|
|
|
|
1907
|
|
|
164
|
|
|
|
|
645
|
|
|
164
|
|
|
|
|
668
|
|
|
164
|
|
|
|
|
500
|
|
|
164
|
|
|
|
|
380
|
|
|
164
|
|
|
|
|
631
|
|
|
164
|
|
|
|
|
282
|
|
192
|
|
|
|
|
|
|
# |
193
|
|
|
|
|
|
|
# We will modify the buffer in-place, therefore we want to |
194
|
|
|
|
|
|
|
# have OUR version of the input. |
195
|
|
|
|
|
|
|
# In addition, this will solve the eventual problem of $input |
196
|
|
|
|
|
|
|
# being a read-only variable |
197
|
|
|
|
|
|
|
# |
198
|
164
|
|
|
|
|
382
|
my $work = $input; |
199
|
164
|
|
|
|
|
2853
|
return $self->_parseByTokens( \$work ); |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# |
203
|
|
|
|
|
|
|
# By token => ConsumerOf['MarpaX::Languages::M4::Role::Value by default'] |
204
|
|
|
|
|
|
|
# By arguments => ArrayRef[ConsumerOf['MarpaX::Languages::M4::Role::Value']] |
205
|
|
|
|
|
|
|
# |
206
|
1
|
50
|
33
|
1
|
|
17124
|
method _parseByGrammar (Ref['SCALAR'] $inputRef, PositiveOrZeroInt $pos, InstanceOf['Marpa::R2::Scanless::G'] $g, Undef|M4Macro $macro? --> Undef|Dict[pos => PositiveOrZeroInt, value => ConsumerOf['MarpaX::Languages::M4::Role::Value']]) { |
|
1
|
50
|
33
|
1
|
|
2
|
|
|
1
|
50
|
|
1
|
|
135
|
|
|
1
|
50
|
|
1
|
|
5
|
|
|
1
|
50
|
|
1
|
|
2
|
|
|
1
|
50
|
|
2018
|
|
123
|
|
|
1
|
50
|
|
|
|
6
|
|
|
1
|
50
|
|
|
|
1
|
|
|
1
|
50
|
|
|
|
91
|
|
|
1
|
50
|
|
|
|
5
|
|
|
1
|
50
|
|
|
|
2
|
|
|
1
|
50
|
|
|
|
107
|
|
|
1
|
100
|
|
|
|
5
|
|
|
1
|
50
|
|
|
|
1
|
|
|
1
|
100
|
|
|
|
2091
|
|
|
1
|
|
|
|
|
2273
|
|
|
2018
|
|
|
|
|
17666
|
|
|
2018
|
|
|
|
|
6254
|
|
|
2018
|
|
|
|
|
4912
|
|
|
2018
|
|
|
|
|
6145
|
|
|
2018
|
|
|
|
|
5157
|
|
|
2018
|
|
|
|
|
3021
|
|
|
2018
|
|
|
|
|
12214
|
|
|
2018
|
|
|
|
|
5455
|
|
|
2018
|
|
|
|
|
4768
|
|
|
2018
|
|
|
|
|
2799
|
|
|
2018
|
|
|
|
|
6417
|
|
|
2018
|
|
|
|
|
4893
|
|
|
2018
|
|
|
|
|
4261
|
|
|
2018
|
|
|
|
|
2848
|
|
|
2018
|
|
|
|
|
7803
|
|
|
2018
|
|
|
|
|
5563
|
|
|
2018
|
|
|
|
|
5296
|
|
|
1854
|
|
|
|
|
2722
|
|
|
1854
|
|
|
|
|
5074
|
|
|
2018
|
|
|
|
|
35596
|
|
207
|
|
|
|
|
|
|
|
208
|
2018
|
|
|
|
|
3216
|
my $maxPos = length( ${$inputRef} ) - 1; |
|
2018
|
|
|
|
|
5151
|
|
209
|
|
|
|
|
|
|
# |
210
|
|
|
|
|
|
|
# Protect the case of empty string. |
211
|
|
|
|
|
|
|
# This is affecting all parsing levels. |
212
|
|
|
|
|
|
|
# |
213
|
2018
|
100
|
|
|
|
4530
|
if ( $pos > $maxPos ) { |
214
|
1
|
|
|
|
|
18
|
return; |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
# |
217
|
|
|
|
|
|
|
# Get the lexemes ordering |
218
|
|
|
|
|
|
|
# |
219
|
2017
|
|
|
|
|
7499
|
my @lexemeNames = $self->parser_tokensPriority(); |
220
|
|
|
|
|
|
|
# |
221
|
|
|
|
|
|
|
# In the context of a macroArguments, unquoted parenthesis |
222
|
|
|
|
|
|
|
# have higher priorities over everything, except quoted string |
223
|
|
|
|
|
|
|
# and comment. |
224
|
|
|
|
|
|
|
# |
225
|
2017
|
100
|
|
|
|
98646
|
if ( $g == $BYMACROARGUMENTS_G ) { |
226
|
1854
|
|
|
|
|
7069
|
unshift( @lexemeNames, 'NOPARAM', 'LPAREN', 'RPAREN', 'COMMA' ); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
2017
|
|
|
|
|
32476
|
my $value = MarpaX::Languages::M4::Impl::Value->new(); |
230
|
2017
|
|
|
|
|
59768
|
my %rc = ( pos => $pos, value => $value ); |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# |
233
|
|
|
|
|
|
|
# Instanciate and start recognizer |
234
|
|
|
|
|
|
|
# |
235
|
2017
|
|
|
|
|
15093
|
my $r = Marpa::R2::Scanless::R->new( |
236
|
|
|
|
|
|
|
{ grammar => $g, |
237
|
|
|
|
|
|
|
semantics_package => 'MarpaX::Languages::M4::Impl::Parser::Actions', |
238
|
|
|
|
|
|
|
exhaustion => 'event', |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# trace_terminals => 1, |
241
|
|
|
|
|
|
|
# trace_values => 1 |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
); |
244
|
|
|
|
|
|
|
# |
245
|
|
|
|
|
|
|
# $prevPos is used only for logging |
246
|
|
|
|
|
|
|
# |
247
|
2017
|
|
|
|
|
593046
|
my $prevPos = $rc{pos} = $pos; |
248
|
|
|
|
|
|
|
# |
249
|
|
|
|
|
|
|
# The stream itself is of no importance. |
250
|
|
|
|
|
|
|
# We use Marpa to drive the context, nothing more. |
251
|
|
|
|
|
|
|
# But is it NOT a hasard that I use the constant '(': |
252
|
|
|
|
|
|
|
# when doing a recursive call using |
253
|
|
|
|
|
|
|
# the macroByarguments grammar, Marpa will expect this |
254
|
|
|
|
|
|
|
# character at the first read, EVEN |
255
|
|
|
|
|
|
|
# if we paused before it. |
256
|
|
|
|
|
|
|
# |
257
|
2017
|
|
|
|
|
8277
|
$r->read( \'(' ); |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
again: |
260
|
4440
|
|
|
|
|
203928
|
while ( $rc{pos} <= $maxPos ) { |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
# $self->logger_debug( '[%d..%d/%d] 20 first characters: %s', |
263
|
|
|
|
|
|
|
# $rc{pos}, $rc{pos}, $maxPos, |
264
|
|
|
|
|
|
|
# substr( ${$inputRef}, $rc{pos}, 20 ) ); |
265
|
|
|
|
|
|
|
|
266
|
23409
|
|
|
|
|
34713
|
my %expected = map { $_ => 1 } @{ $r->terminals_expected }; |
|
186963
|
|
|
|
|
2554807
|
|
|
23409
|
|
|
|
|
65883
|
|
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
# $self->logger_debug( |
269
|
|
|
|
|
|
|
# '[%d..%d/%d] Expected terminals: %s', |
270
|
|
|
|
|
|
|
# $rc{pos}, $rc{pos}, $maxPos, |
271
|
|
|
|
|
|
|
# [ keys %expected ] |
272
|
|
|
|
|
|
|
# ); |
273
|
|
|
|
|
|
|
|
274
|
23409
|
100
|
|
|
|
99069
|
if ( $r->exhausted ) { |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# $self->logger_debug( '[%d..%d/%d] Parse is exhausted', |
277
|
|
|
|
|
|
|
# $rc{pos}, $rc{pos}, $maxPos ); |
278
|
|
|
|
|
|
|
|
279
|
1823
|
|
|
|
|
19286
|
last; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
21586
|
|
|
|
|
273627
|
my $lexemeValue; |
283
|
|
|
|
|
|
|
my $lexemeLength; |
284
|
21586
|
|
|
|
|
0
|
my $lexeme; |
285
|
|
|
|
|
|
|
|
286
|
21586
|
|
|
|
|
0
|
my $QuotedstringValue; |
287
|
21586
|
|
|
|
|
0
|
my $QuotedstringLength; |
288
|
21586
|
|
|
|
|
55017
|
my $isQuotedString = false; |
289
|
|
|
|
|
|
|
|
290
|
21586
|
|
|
|
|
69566
|
my $CommentValue; |
291
|
|
|
|
|
|
|
my $CommentLength; |
292
|
21586
|
|
|
|
|
43762
|
my $isComment = false; |
293
|
|
|
|
|
|
|
|
294
|
21586
|
|
|
|
|
70240
|
my $canCollectArguments = true; |
295
|
21586
|
100
|
|
|
|
80174
|
if ( $g == $BYMACROARGUMENTS_G ) { |
296
|
16948
|
|
|
|
|
33977
|
my $blockOk = false; |
297
|
|
|
|
|
|
|
try { |
298
|
|
|
|
|
|
|
$isQuotedString |
299
|
16948
|
|
|
|
|
354367
|
= $self->parser_isQuotedstring( ${$inputRef}, |
300
|
|
|
|
|
|
|
$rc{pos}, |
301
|
16948
|
|
|
16948
|
|
391720
|
$maxPos, \$QuotedstringValue, \$QuotedstringLength ); |
302
|
|
|
|
|
|
|
$isComment |
303
|
16948
|
|
|
|
|
251727
|
= $self->parser_isComment( ${$inputRef}, $rc{pos}, |
304
|
16948
|
|
|
|
|
361943
|
$maxPos, \$CommentValue, \$CommentLength ); |
305
|
16948
|
|
100
|
|
|
382419
|
$canCollectArguments = !$isQuotedString && !$isComment; |
306
|
16948
|
|
|
|
|
37119
|
$blockOk = true; |
307
|
16948
|
|
|
|
|
123657
|
}; |
308
|
16948
|
50
|
|
|
|
242980
|
if ( !$blockOk ) { |
309
|
0
|
|
|
|
|
0
|
goto return_error; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
21586
|
|
|
|
|
47045
|
foreach (@lexemeNames) { |
314
|
112029
|
100
|
|
|
|
287207
|
if ( $_ eq 'NOPARAM' ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
315
|
16948
|
100
|
66
|
|
|
49632
|
if ( exists( $expected{NOPARAM} ) |
316
|
|
|
|
|
|
|
&& $canCollectArguments ) |
317
|
|
|
|
|
|
|
{ |
318
|
1854
|
|
|
|
|
3632
|
pos( ${$inputRef} ) = $rc{pos}; |
|
1854
|
|
|
|
|
5848
|
|
319
|
1854
|
100
|
|
|
|
3991
|
if ( ${$inputRef} =~ /\G\(\s*\)/s ) { |
|
1854
|
|
|
|
|
10282
|
|
320
|
15
|
|
|
|
|
35
|
$lexeme = 'NOPARAM'; |
321
|
15
|
|
|
|
|
29
|
$lexemeValue = substr( ${$inputRef}, $-[0], |
|
15
|
|
|
|
|
114
|
|
322
|
|
|
|
|
|
|
$+[0] - $-[0] ); |
323
|
15
|
|
|
|
|
69
|
$lexemeLength = $+[0] - $-[0]; |
324
|
15
|
|
|
|
|
38
|
last; |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
elsif ( $_ eq 'LPAREN' ) { |
329
|
16933
|
100
|
66
|
|
|
50584
|
if ( exists( $expected{LPAREN} ) |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
330
|
|
|
|
|
|
|
&& $canCollectArguments |
331
|
12860
|
|
|
|
|
20570
|
&& do { pos( ${$inputRef} ) = $rc{pos}; 1 } |
|
12860
|
|
|
|
|
33196
|
|
|
12860
|
|
|
|
|
36409
|
|
332
|
12860
|
|
|
|
|
55501
|
&& ${$inputRef} =~ /\G\(\s*/ |
333
|
|
|
|
|
|
|
) |
334
|
|
|
|
|
|
|
{ |
335
|
1870
|
|
|
|
|
3120
|
$lexeme = 'LPAREN'; |
336
|
1870
|
|
|
|
|
12475
|
$lexemeLength = $+[0] - $-[0]; |
337
|
|
|
|
|
|
|
$lexemeValue |
338
|
1870
|
|
|
|
|
3469
|
= substr( ${$inputRef}, $-[0], $lexemeLength ); |
|
1870
|
|
|
|
|
7930
|
|
339
|
1870
|
|
|
|
|
3655
|
last; |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
elsif ( $_ eq 'RPAREN' ) { |
343
|
15063
|
100
|
66
|
|
|
45460
|
if ( exists( $expected{RPAREN} ) |
|
|
|
100
|
|
|
|
|
344
|
|
|
|
|
|
|
&& $canCollectArguments |
345
|
10990
|
|
|
|
|
35626
|
&& substr( ${$inputRef}, $rc{pos}, 1 ) eq ')' ) |
346
|
|
|
|
|
|
|
{ |
347
|
1869
|
|
|
|
|
3355
|
$lexeme = 'RPAREN'; |
348
|
1869
|
|
|
|
|
2887
|
$lexemeValue = ')'; |
349
|
1869
|
|
|
|
|
2830
|
$lexemeLength = 1; |
350
|
1869
|
|
|
|
|
3188
|
last; |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
elsif ( $_ eq 'COMMA' ) { |
354
|
13194
|
100
|
100
|
|
|
37783
|
if ( exists( $expected{COMMA} ) && $canCollectArguments ) |
355
|
|
|
|
|
|
|
{ |
356
|
9025
|
|
|
|
|
12742
|
pos( ${$inputRef} ) = $rc{pos}; |
|
9025
|
|
|
|
|
17202
|
|
357
|
9025
|
100
|
|
|
|
14742
|
if ( ${$inputRef} =~ /\G,\s*/s ) { |
|
9025
|
|
|
|
|
26140
|
|
358
|
2666
|
|
|
|
|
4447
|
$lexeme = 'COMMA'; |
359
|
2666
|
|
|
|
|
3545
|
$lexemeValue = substr( ${$inputRef}, $-[0], |
|
2666
|
|
|
|
|
25310
|
|
360
|
|
|
|
|
|
|
$+[0] - $-[0] ); |
361
|
2666
|
|
|
|
|
16670
|
$lexemeLength = $+[0] - $-[0]; |
362
|
2666
|
|
|
|
|
5179
|
last; |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
else { |
367
|
49891
|
100
|
100
|
|
|
198352
|
if ( $g == $BYMACROARGUMENTS_G && $_ eq 'QUOTEDSTRING' ) { |
|
|
100
|
100
|
|
|
|
|
368
|
|
|
|
|
|
|
# |
369
|
|
|
|
|
|
|
# Already done in the context of macro arguments grammar |
370
|
|
|
|
|
|
|
# |
371
|
9654
|
100
|
|
|
|
20712
|
if ($isQuotedString) { |
372
|
4068
|
|
|
|
|
6034
|
$lexeme = $_; |
373
|
4068
|
|
|
|
|
6468
|
$lexemeValue = $QuotedstringValue; |
374
|
4068
|
|
|
|
|
5473
|
$lexemeLength = $QuotedstringLength; |
375
|
4068
|
|
|
|
|
6942
|
last; |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
elsif ( $g == $BYMACROARGUMENTS_G && $_ eq 'COMMENT' ) { |
379
|
|
|
|
|
|
|
# |
380
|
|
|
|
|
|
|
# Already done in the context of macro arguments grammar |
381
|
|
|
|
|
|
|
# |
382
|
10528
|
100
|
|
|
|
23564
|
if ($isComment) { |
383
|
5
|
|
|
|
|
11
|
$lexeme = $_; |
384
|
5
|
|
|
|
|
9
|
$lexemeValue = $CommentValue; |
385
|
5
|
|
|
|
|
10
|
$lexemeLength = $CommentLength; |
386
|
5
|
|
|
|
|
10
|
last; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
} |
389
|
|
|
|
|
|
|
else { |
390
|
|
|
|
|
|
|
# |
391
|
|
|
|
|
|
|
# QUOTEDSTRING is not already done if not |
392
|
|
|
|
|
|
|
# in the context of macro arguments grammar |
393
|
|
|
|
|
|
|
# Ditto for COMMENT. |
394
|
|
|
|
|
|
|
# |
395
|
29709
|
|
|
|
|
80922
|
my $method = 'parser_is' . ucfirst( lc($_) ); |
396
|
29709
|
|
|
|
|
58553
|
my $blockOk = false; |
397
|
29709
|
|
|
|
|
89726
|
my $isToken; |
398
|
|
|
|
|
|
|
try { |
399
|
29709
|
|
|
|
|
598436
|
$isToken = $self->$method( ${$inputRef}, $rc{pos}, |
400
|
29709
|
|
|
29709
|
|
650499
|
$maxPos, \$lexemeValue, \$lexemeLength ); |
401
|
29705
|
|
|
|
|
688320
|
$blockOk = true; |
402
|
29709
|
|
|
|
|
155005
|
}; |
403
|
29709
|
100
|
|
|
|
403023
|
if ( !$blockOk ) { |
404
|
4
|
|
|
|
|
124
|
goto return_error; |
405
|
|
|
|
|
|
|
} |
406
|
29705
|
100
|
|
|
|
78703
|
if ($isToken) { |
407
|
11089
|
|
|
|
|
17552
|
$lexeme = $_; |
408
|
11089
|
|
|
|
|
21406
|
last; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
} |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
# |
414
|
|
|
|
|
|
|
# Nothing ? |
415
|
|
|
|
|
|
|
# |
416
|
21582
|
50
|
|
|
|
53832
|
if ( Undef->check($lexeme) ) { |
417
|
0
|
|
|
|
|
0
|
goto return_error; |
418
|
|
|
|
|
|
|
} |
419
|
|
|
|
|
|
|
# |
420
|
|
|
|
|
|
|
# If it is a word, check if this is eventually a macro |
421
|
|
|
|
|
|
|
# |
422
|
21582
|
100
|
|
|
|
222718
|
if ( $lexeme eq 'WORD' ) { |
423
|
3089
|
|
|
|
|
5026
|
my $thisMacro; |
424
|
|
|
|
|
|
|
my $lparenPos; |
425
|
3089
|
100
|
|
|
|
4268
|
if ($self->parser_isMacro( |
426
|
3089
|
|
|
|
|
54482
|
${$inputRef}, $rc{pos}, $maxPos, |
427
|
|
|
|
|
|
|
$lexemeValue, $lexemeLength, \$thisMacro, |
428
|
|
|
|
|
|
|
\$lparenPos |
429
|
|
|
|
|
|
|
) |
430
|
|
|
|
|
|
|
) |
431
|
|
|
|
|
|
|
{ |
432
|
2441
|
|
|
|
|
90586
|
my $canTrace = $self->_canTrace($thisMacro); |
433
|
2441
|
|
|
|
|
89566
|
my $macroCallId |
434
|
|
|
|
|
|
|
= $self->impl_macroExecuteHeader( $thisMacro, |
435
|
|
|
|
|
|
|
$canTrace ); |
436
|
|
|
|
|
|
|
# |
437
|
|
|
|
|
|
|
# Collect macro arguments |
438
|
|
|
|
|
|
|
# |
439
|
2441
|
|
|
|
|
19612
|
my @args = (); |
440
|
|
|
|
|
|
|
|
441
|
2441
|
100
|
|
|
|
5685
|
if ( $lparenPos >= 0 ) { |
442
|
|
|
|
|
|
|
|
443
|
1854
|
|
|
|
|
29447
|
$self->_set__parse_level( $self->_parse_level + 1 ); |
444
|
1854
|
|
|
|
|
89412
|
my $dict = $self->_parseByGrammar( |
445
|
|
|
|
|
|
|
$inputRef, $lparenPos, |
446
|
|
|
|
|
|
|
$BYMACROARGUMENTS_G, $thisMacro |
447
|
|
|
|
|
|
|
); |
448
|
1853
|
|
|
|
|
144283
|
$self->_set__parse_level( $self->_parse_level - 1 ); |
449
|
1853
|
50
|
|
|
|
69747
|
if ( Undef->check($dict) ) { |
450
|
0
|
|
|
|
|
0
|
goto return_error; |
451
|
|
|
|
|
|
|
} |
452
|
1853
|
|
|
|
|
19559
|
@args = $dict->{value}->value_elements; |
453
|
1853
|
|
|
|
|
82100
|
$lexemeLength = $dict->{pos} - $rc{pos}; |
454
|
|
|
|
|
|
|
} |
455
|
|
|
|
|
|
|
# |
456
|
|
|
|
|
|
|
# It is the reponsability of implementation to make sure |
457
|
|
|
|
|
|
|
# that a macro never croaks. |
458
|
|
|
|
|
|
|
# |
459
|
|
|
|
|
|
|
$lexemeValue |
460
|
2440
|
|
|
|
|
39873
|
= $self->impl_macroExecuteNoHeader( $thisMacro, |
461
|
|
|
|
|
|
|
$macroCallId, $canTrace, @args ); |
462
|
|
|
|
|
|
|
# |
463
|
|
|
|
|
|
|
# Eventual postmatch length |
464
|
|
|
|
|
|
|
# |
465
|
|
|
|
|
|
|
$lexemeLength |
466
|
|
|
|
|
|
|
+= $thisMacro->macro_postMatchLengthExecute( $self, |
467
|
2438
|
|
|
|
|
19920
|
${$inputRef}, $rc{pos} + $lexemeLength, $maxPos ); |
|
2438
|
|
|
|
|
38698
|
|
468
|
|
|
|
|
|
|
# |
469
|
|
|
|
|
|
|
# Input is changing |
470
|
|
|
|
|
|
|
# |
471
|
2438
|
100
|
|
|
|
9169
|
if ( M4Macro->check($lexemeValue) ) { |
472
|
|
|
|
|
|
|
# |
473
|
|
|
|
|
|
|
# Protect the case of M4Macro |
474
|
|
|
|
|
|
|
# |
475
|
15
|
|
|
|
|
436
|
$lexeme = 'ANYTHING'; |
476
|
|
|
|
|
|
|
} |
477
|
|
|
|
|
|
|
else { |
478
|
|
|
|
|
|
|
# $self->logger_debug( |
479
|
|
|
|
|
|
|
# '[%d..%d/%d] Input is changing: replace %s by %s', |
480
|
|
|
|
|
|
|
# $rc{pos}, |
481
|
|
|
|
|
|
|
# $rc{pos}, |
482
|
|
|
|
|
|
|
# $maxPos, |
483
|
|
|
|
|
|
|
# substr( |
484
|
|
|
|
|
|
|
# ${$inputRef}, $rc{pos}, $lexemeLength |
485
|
|
|
|
|
|
|
# ), |
486
|
|
|
|
|
|
|
# $lexemeValue |
487
|
|
|
|
|
|
|
# ); |
488
|
|
|
|
|
|
|
substr( |
489
|
2423
|
|
|
|
|
11687
|
${$inputRef}, $rc{pos}, |
490
|
2423
|
|
|
|
|
30099
|
$lexemeLength, $lexemeValue |
491
|
|
|
|
|
|
|
); |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
# $self->logger_debug( '[%d..%d/%d] New input: %s', |
494
|
|
|
|
|
|
|
# $rc{pos}, $rc{pos}, $maxPos, ${$inputRef} ); |
495
|
|
|
|
|
|
|
|
496
|
2423
|
|
|
|
|
4389
|
$maxPos = length( ${$inputRef} ) - 1; |
|
2423
|
|
|
|
|
8099
|
|
497
|
2423
|
|
|
|
|
86677
|
goto again; |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
else { |
501
|
|
|
|
|
|
|
# $self->logger_debug( |
502
|
|
|
|
|
|
|
# '[%d..%d/%d] %s is not an acceptable macro call', |
503
|
|
|
|
|
|
|
# $rc{pos}, $rc{pos}, $maxPos, $lexemeValue ); |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
} |
506
|
|
|
|
|
|
|
# |
507
|
|
|
|
|
|
|
# When _parse_level is zero, the current token has been fully |
508
|
|
|
|
|
|
|
# parsed, and its output is to |
509
|
|
|
|
|
|
|
# to be immediately "flushed". |
510
|
|
|
|
|
|
|
# We do not need to do a lexeme_read(), nor a resume in this case: |
511
|
|
|
|
|
|
|
# we know where we are. |
512
|
|
|
|
|
|
|
# |
513
|
19156
|
100
|
|
|
|
75737
|
if ( $self->_parse_level > 0 ) { |
514
|
16277
|
|
|
|
|
59250
|
$r->lexeme_read( $lexeme, 0, 1, $lexemeValue ); |
515
|
16277
|
|
|
|
|
1388701
|
$prevPos = $rc{pos}; |
516
|
16277
|
|
|
|
|
71109
|
$rc{pos} += $lexemeLength; |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
# $self->logger_debug( '[%d->%d/%d] %s: %s', |
519
|
|
|
|
|
|
|
# $prevPos, $rc{pos}, $maxPos, $lexeme, $lexemeValue ); |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
# |
522
|
|
|
|
|
|
|
# We can safely ignore the events from lexeme_read(), |
523
|
|
|
|
|
|
|
# because we made sure in the grammar that resume() will |
524
|
|
|
|
|
|
|
# NOT advance the position, thanks to those events: |
525
|
|
|
|
|
|
|
# |
526
|
|
|
|
|
|
|
# ^token |
527
|
|
|
|
|
|
|
# ^ANYTHING |
528
|
|
|
|
|
|
|
# macroArguments$ |
529
|
|
|
|
|
|
|
# token$ |
530
|
|
|
|
|
|
|
# |
531
|
|
|
|
|
|
|
# macroArguments$, if it happens will always be standalone. |
532
|
|
|
|
|
|
|
# token$, when it happen, can be mixed with ^token or |
533
|
|
|
|
|
|
|
# ^ANYTHING. |
534
|
|
|
|
|
|
|
# |
535
|
|
|
|
|
|
|
# Please note that we do not use resume(). |
536
|
|
|
|
|
|
|
# |
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
else { |
539
|
|
|
|
|
|
|
# |
540
|
|
|
|
|
|
|
# We are at the top level: flush to current diversion |
541
|
|
|
|
|
|
|
# |
542
|
|
|
|
|
|
|
# $self->logger_debug( '[%d->%d/%d] %s: %s', |
543
|
|
|
|
|
|
|
# $prevPos, $rc{pos}, $maxPos, $lexeme, $lexemeValue ); |
544
|
|
|
|
|
|
|
|
545
|
2879
|
|
|
|
|
49662
|
my $tmpValue = MarpaX::Languages::M4::Impl::Value->new() |
546
|
|
|
|
|
|
|
->value_push($lexemeValue); |
547
|
2879
|
|
|
|
|
166658
|
$self->impl_appendValue( |
548
|
|
|
|
|
|
|
$tmpValue->value_concat->value_firstElement ); |
549
|
2879
|
|
|
|
|
7058
|
$prevPos = $rc{pos}; |
550
|
2879
|
|
|
|
|
16403
|
$rc{pos} += $lexemeLength; |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
2010
|
100
|
|
|
|
6618
|
if ( $self->_parse_level > 0 ) { |
555
|
|
|
|
|
|
|
# |
556
|
|
|
|
|
|
|
# We are in the context of a recursive call: the output |
557
|
|
|
|
|
|
|
# is of concern for a macro that called us. |
558
|
|
|
|
|
|
|
# |
559
|
1856
|
|
|
|
|
4027
|
local $MarpaX::Languages::M4::Impl::Parser::macro = $macro; |
560
|
|
|
|
|
|
|
# |
561
|
|
|
|
|
|
|
# For $r->value() optimisations |
562
|
|
|
|
|
|
|
# |
563
|
1856
|
|
|
|
|
3100
|
state $registrations = undef; |
564
|
|
|
|
|
|
|
|
565
|
1856
|
100
|
|
|
|
3920
|
if (defined($registrations)) { |
566
|
1855
|
|
|
|
|
6420
|
$r->registrations($registrations); |
567
|
|
|
|
|
|
|
} |
568
|
1856
|
|
|
|
|
7701
|
my $valueRef = $r->value; |
569
|
1856
|
100
|
|
|
|
177424
|
if (! defined($registrations)) { |
570
|
1
|
|
|
|
|
9
|
$registrations = $r->registrations(); |
571
|
|
|
|
|
|
|
} |
572
|
1856
|
100
|
66
|
|
|
4931
|
if ( Undef->check($valueRef) || Undef->check( ${$valueRef} ) ) { |
|
1855
|
|
|
|
|
22763
|
|
573
|
1
|
|
|
|
|
16
|
goto return_error; |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
1855
|
|
|
|
|
12735
|
$rc{value} = ${$valueRef}; |
|
1855
|
|
|
|
|
4426
|
|
577
|
|
|
|
|
|
|
} |
578
|
|
|
|
|
|
|
else { |
579
|
|
|
|
|
|
|
# |
580
|
|
|
|
|
|
|
# We are at the top level: the output has already been |
581
|
|
|
|
|
|
|
# "flushed" to whatever the current diversion said to. |
582
|
|
|
|
|
|
|
# |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
# $self->logger_debug( '[%d..%d/%d] => %s', |
586
|
|
|
|
|
|
|
# $rc{pos}, $rc{pos}, $maxPos, \%rc ); |
587
|
|
|
|
|
|
|
|
588
|
2009
|
|
|
|
|
77502
|
return \%rc; |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
return_error: |
591
|
|
|
|
|
|
|
# |
592
|
|
|
|
|
|
|
# We propagate the undef to all levels except number 0 |
593
|
|
|
|
|
|
|
# |
594
|
5
|
100
|
|
|
|
24
|
if ( $self->_parse_level > 0 ) { |
595
|
1
|
50
|
33
|
|
|
33
|
if ( $self->_parse_level == 1 && $self->impl_eoi ) { |
596
|
|
|
|
|
|
|
# |
597
|
|
|
|
|
|
|
# We want the parsing to stop now |
598
|
|
|
|
|
|
|
# |
599
|
1
|
|
|
|
|
24
|
$self->impl_raiseException('EOF during argument collection'); |
600
|
|
|
|
|
|
|
} |
601
|
0
|
|
|
|
|
0
|
return; |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
else { |
604
|
4
|
|
|
|
|
138
|
return \%rc; |
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
} |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
# |
609
|
|
|
|
|
|
|
# M4 says that a token is processed as soon as it is recognized. |
610
|
|
|
|
|
|
|
# So we loop on token recognition |
611
|
|
|
|
|
|
|
# |
612
|
1
|
50
|
33
|
1
|
|
2665
|
method _parseByTokens (Ref['SCALAR'] $inputRef --> Str) { |
|
1
|
50
|
|
1
|
|
2
|
|
|
1
|
50
|
|
164
|
|
120
|
|
|
1
|
50
|
|
|
|
5
|
|
|
1
|
50
|
|
|
|
2
|
|
|
1
|
|
|
|
|
169
|
|
|
1
|
|
|
|
|
16478
|
|
|
164
|
|
|
|
|
1788
|
|
|
164
|
|
|
|
|
521
|
|
|
164
|
|
|
|
|
590
|
|
|
164
|
|
|
|
|
565
|
|
|
164
|
|
|
|
|
315
|
|
|
164
|
|
|
|
|
1263
|
|
|
164
|
|
|
|
|
405
|
|
613
|
|
|
|
|
|
|
|
614
|
164
|
|
|
|
|
2965
|
my $rc = $self->_parseByGrammar( $inputRef, 0, $BYTOKEN_G ); |
615
|
161
|
100
|
|
|
|
10380
|
if ( !Undef->check($rc) ) { |
616
|
160
|
|
|
|
|
1640
|
return substr( ${$inputRef}, $rc->{pos} ); |
|
160
|
|
|
|
|
3396
|
|
617
|
|
|
|
|
|
|
} |
618
|
|
|
|
|
|
|
|
619
|
1
|
|
|
|
|
18
|
return ${$inputRef}; |
|
1
|
|
|
|
|
16
|
|
620
|
|
|
|
|
|
|
} |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
1; |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
__END__ |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
=pod |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
=encoding UTF-8 |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
=head1 NAME |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
MarpaX::Languages::M4::Impl::Parser - M4 Marpa parser |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
=head1 VERSION |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
version 0.018 |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
=head1 AUTHOR |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
Jean-Damien Durand <jeandamiendurand@free.fr> |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
This software is copyright (c) 2015 by Jean-Damien Durand. |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
649
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=cut |