line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------------------------------- # |
2
|
|
|
|
|
|
|
# MarpaX::MarpaGen # |
3
|
|
|
|
|
|
|
# # |
4
|
|
|
|
|
|
|
# translate the parsed antlr4 rules to Marpa::R2 syntax. # |
5
|
|
|
|
|
|
|
# # |
6
|
|
|
|
|
|
|
# V 0.9.6 # |
7
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------------------------------- # |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package MarpaX::G4; |
10
|
|
|
|
|
|
|
|
11
|
2
|
|
|
2
|
|
839
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
51
|
|
12
|
2
|
|
|
2
|
|
9
|
use warnings FATAL => 'all'; |
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
51
|
|
13
|
|
|
|
|
|
|
|
14
|
2
|
|
|
2
|
|
481
|
use Data::Dumper; |
|
2
|
|
|
|
|
5431
|
|
|
2
|
|
|
|
|
85
|
|
15
|
|
|
|
|
|
|
|
16
|
2
|
|
|
2
|
|
947
|
use MarpaX::G4::Parser; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
59
|
|
17
|
2
|
|
|
2
|
|
838
|
use MarpaX::G4::Symboltable; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
52
|
|
18
|
2
|
|
|
2
|
|
1105
|
use MarpaX::G4::MarpaGen; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
1384
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our $VERSION = '0.9.6'; |
21
|
|
|
|
|
|
|
our $optstr = 'cdefghiko:prs:tuv'; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub new |
24
|
|
|
|
|
|
|
{ |
25
|
1
|
|
|
1
|
0
|
1155
|
my $invocant = shift; |
26
|
1
|
|
33
|
|
|
6
|
my $class = ref($invocant) || $invocant; # Object or class name |
27
|
1
|
|
|
|
|
2
|
my $self = {}; # initiate our handy hashref |
28
|
1
|
|
|
|
|
1
|
bless($self,$class); # make it usable |
29
|
|
|
|
|
|
|
|
30
|
1
|
|
|
|
|
3
|
return $self; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub printHelpScreen |
34
|
|
|
|
|
|
|
{ |
35
|
0
|
|
|
0
|
0
|
0
|
my ($scriptName) = @_; |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
0
|
my $usage = "Usage: $scriptName [-cdefghikprtuv] [-s ] [-o ] [ ...]"; |
38
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
0
|
my @helptext = ( |
40
|
|
|
|
|
|
|
"$scriptName - Antlr4 to MarpaX converter" |
41
|
|
|
|
|
|
|
,"" |
42
|
|
|
|
|
|
|
,"$usage" |
43
|
|
|
|
|
|
|
,"" |
44
|
|
|
|
|
|
|
,"-c strip all comments and actions (except inline actions)" |
45
|
|
|
|
|
|
|
,"-d dump the parse tree" |
46
|
|
|
|
|
|
|
,"-e embed the g4 inline actions into the marpa grammar" |
47
|
|
|
|
|
|
|
," (default : prefix as comments ahead of the rule)" |
48
|
|
|
|
|
|
|
,"-f convert fragments to classes where applicable" |
49
|
|
|
|
|
|
|
,"-g convert lazy to greedy quantifiers" |
50
|
|
|
|
|
|
|
," (CAVEAT: this might change the grammar semantics)" |
51
|
|
|
|
|
|
|
,"-h print this help and exit" |
52
|
|
|
|
|
|
|
,"-i ignore redirects (don't discard redirected rules)" |
53
|
|
|
|
|
|
|
,"-k build case-insensitive keywords from single-letter fragments" |
54
|
|
|
|
|
|
|
,"-o specify the output file. default is stdout" |
55
|
|
|
|
|
|
|
,"-p strip inline comments and actions" |
56
|
|
|
|
|
|
|
,"-r verify the consistency of the symbol table" |
57
|
|
|
|
|
|
|
,"-s specify the start rule of the grammar" |
58
|
|
|
|
|
|
|
," (default: 1st rule of the 1st input file)" |
59
|
|
|
|
|
|
|
,"-t trace the grammar generation" |
60
|
|
|
|
|
|
|
,"-u make literals and classes case-insensitive" |
61
|
|
|
|
|
|
|
,"-v dump the symbol table" |
62
|
|
|
|
|
|
|
); |
63
|
|
|
|
|
|
|
|
64
|
0
|
|
|
|
|
0
|
map { print $_ . "\n"; } @helptext; |
|
0
|
|
|
|
|
0
|
|
65
|
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
0
|
exit 0; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
## |
70
|
|
|
|
|
|
|
# readFile: swallow an entire input file into a string |
71
|
|
|
|
|
|
|
## |
72
|
|
|
|
|
|
|
sub readFile |
73
|
|
|
|
|
|
|
{ |
74
|
0
|
|
|
0
|
0
|
0
|
my ($infile) = @_; |
75
|
|
|
|
|
|
|
|
76
|
0
|
0
|
|
|
|
0
|
my $inph = *STDIN if $infile eq '-'; |
77
|
0
|
0
|
0
|
|
|
0
|
open($inph, "< $infile") || die "can't open input file $infile : $!" if $infile ne '-'; |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
my $file_text = do |
80
|
0
|
|
|
|
|
0
|
{ |
81
|
0
|
|
|
|
|
0
|
local $/; |
82
|
0
|
|
|
|
|
0
|
<$inph>; |
83
|
|
|
|
|
|
|
}; |
84
|
|
|
|
|
|
|
|
85
|
0
|
0
|
|
|
|
0
|
close($inph) if $infile ne '-'; |
86
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
0
|
return $file_text; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
## |
91
|
|
|
|
|
|
|
# processSymboltable: generate the output grammar from the symbol table |
92
|
|
|
|
|
|
|
## |
93
|
|
|
|
|
|
|
sub processSymboltable |
94
|
|
|
|
|
|
|
{ |
95
|
1
|
|
|
1
|
0
|
3
|
my ($self, $symboltable, $options ) = @_; |
96
|
|
|
|
|
|
|
|
97
|
1
|
50
|
|
|
|
4
|
if ( exists $options->{v} ) |
98
|
|
|
|
|
|
|
{ |
99
|
0
|
|
|
|
|
0
|
$Data::Dumper::Indent = 1; |
100
|
0
|
|
|
|
|
0
|
print Dumper($symboltable); |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
1
|
50
|
|
|
|
4
|
$symboltable->setStartRule($options->{s}) if exists $options->{s}; |
104
|
1
|
50
|
|
|
|
3
|
$symboltable->validateSymbolTable() if exists $options->{r}; |
105
|
|
|
|
|
|
|
|
106
|
1
|
|
|
|
|
11
|
my $generator = new MarpaX::G4::MarpaGen; |
107
|
|
|
|
|
|
|
|
108
|
1
|
50
|
|
|
|
4
|
$generator->stripallcomments if exists $options->{c}; |
109
|
1
|
50
|
|
|
|
4
|
$generator->embedactions if exists $options->{e}; |
110
|
1
|
50
|
|
|
|
7
|
$generator->fragment2class if exists $options->{f}; |
111
|
1
|
50
|
|
|
|
5
|
$generator->shiftlazytogreedy if exists $options->{g}; |
112
|
1
|
50
|
|
|
|
7
|
$generator->buildkeywords if exists $options->{k}; |
113
|
1
|
50
|
|
|
|
4
|
$generator->stripactions if exists $options->{p}; |
114
|
1
|
50
|
|
|
|
3
|
$generator->setVerbosity(2) if exists $options->{t}; |
115
|
1
|
50
|
33
|
|
|
9
|
$generator->matchcaseinsensitive if exists $options->{u} || exists $options->{k}; |
116
|
|
|
|
|
|
|
|
117
|
1
|
|
|
|
|
2
|
my $outputfile = '-'; |
118
|
1
|
50
|
|
|
|
5
|
$outputfile = $options->{o} if exists $options->{o}; |
119
|
1
|
|
|
|
|
6
|
$generator->setoutputfile($outputfile); |
120
|
|
|
|
|
|
|
|
121
|
1
|
|
|
|
|
5
|
$generator->generate($symboltable); |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
## |
125
|
|
|
|
|
|
|
# translatestring: parse the antlr4 input grammar from '$grammartext', |
126
|
|
|
|
|
|
|
# generate the Marpa::R2 output grammar. |
127
|
|
|
|
|
|
|
## |
128
|
|
|
|
|
|
|
sub translatestring |
129
|
|
|
|
|
|
|
{ |
130
|
1
|
|
|
1
|
0
|
14
|
my ( $self, $grammartext, $options ) = @_; |
131
|
|
|
|
|
|
|
|
132
|
1
|
|
|
|
|
4
|
my $parser = new MarpaX::G4::Parser; |
133
|
1
|
50
|
|
|
|
8
|
$parser->enabletrace if exists $options->{t}; |
134
|
1
|
50
|
|
|
|
4
|
$parser->ignoreredirect if exists $options->{i}; |
135
|
|
|
|
|
|
|
|
136
|
1
|
|
|
|
|
15
|
my $symboltable = new MarpaX::G4::Symboltable; |
137
|
|
|
|
|
|
|
|
138
|
1
|
|
|
|
|
6
|
my $data = $parser->parse($grammartext); |
139
|
1
|
50
|
|
|
|
8
|
if ( exists $options->{d} ) |
140
|
|
|
|
|
|
|
{ |
141
|
0
|
|
|
|
|
0
|
printf "===\n=== Parsed Hashtable\n===\n"; |
142
|
0
|
|
|
|
|
0
|
$Data::Dumper::Indent = 2; |
143
|
0
|
|
|
|
|
0
|
print Dumper($data); |
144
|
|
|
|
|
|
|
} |
145
|
1
|
|
|
|
|
8
|
$symboltable->importParseTree($data); |
146
|
|
|
|
|
|
|
|
147
|
1
|
|
|
|
|
6
|
$self->processSymboltable($symboltable, $options); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
## |
151
|
|
|
|
|
|
|
# translatefiles: parse the antlr4 input grammar from the input file(s), |
152
|
|
|
|
|
|
|
# generate the Marpa::R2 output grammar. |
153
|
|
|
|
|
|
|
## |
154
|
|
|
|
|
|
|
sub translatefiles |
155
|
|
|
|
|
|
|
{ |
156
|
0
|
|
|
0
|
0
|
|
my ( $self, $inputfiles, $options ) = @_; |
157
|
|
|
|
|
|
|
|
158
|
0
|
|
|
|
|
|
my $parser = new MarpaX::G4::Parser; |
159
|
0
|
0
|
|
|
|
|
$parser->enabletrace if exists $options->{t}; |
160
|
0
|
0
|
|
|
|
|
$parser->ignoreredirect if exists $options->{i}; |
161
|
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
my $symboltable = new MarpaX::G4::Symboltable; |
163
|
|
|
|
|
|
|
|
164
|
0
|
|
|
|
|
|
while (scalar @$inputfiles) |
165
|
|
|
|
|
|
|
{ |
166
|
0
|
|
|
|
|
|
my $infile = shift @$inputfiles; |
167
|
0
|
|
|
|
|
|
my $grammartext = readFile($infile); |
168
|
0
|
|
|
|
|
|
my $data = $parser->parse($grammartext); |
169
|
0
|
0
|
|
|
|
|
if ( exists $options->{d} ) |
170
|
|
|
|
|
|
|
{ |
171
|
0
|
|
|
|
|
|
$Data::Dumper::Indent = 2; |
172
|
0
|
|
|
|
|
|
print Dumper($data); |
173
|
|
|
|
|
|
|
} |
174
|
0
|
|
|
|
|
|
$symboltable->importParseTree($data); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
|
$self->processSymboltable($symboltable, $options); |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
1; |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# ABSTRACT: translate parsed antlr4 rules to Marpa2 syntax |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=head1 SYNOPSIS |
185
|
|
|
|
|
|
|
use MarpaX::G4; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=head1 DESCRIPTION |
188
|
|
|
|
|
|
|
Translate the rules from the symbol table created from the imported ANTLR4 grammar |
189
|
|
|
|
|
|
|
into Marpa syntax and write them to output. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=cut |