our
$VERSION
=
'0.9.6'
;
our
$optstr
=
'cdefghiko:prs:tuv'
;
sub
new
{
my
$invocant
=
shift
;
my
$class
=
ref
(
$invocant
) ||
$invocant
;
my
$self
= {};
bless
(
$self
,
$class
);
return
$self
;
}
sub
printHelpScreen
{
my
(
$scriptName
) =
@_
;
my
$usage
=
"Usage: $scriptName [-cdefghikprtuv] [-s <startsymbol>] [-o <outputfile>] <file1>[ <file2> ...]"
;
my
@helptext
= (
"$scriptName - Antlr4 to MarpaX converter"
,
""
,
"$usage"
,
""
,
"-c strip all comments and actions (except inline actions)"
,
"-d dump the parse tree"
,
"-e embed the g4 inline actions into the marpa grammar"
,
" (default : prefix as comments ahead of the rule)"
,
"-f convert fragments to classes where applicable"
,
"-g convert lazy to greedy quantifiers"
,
" (CAVEAT: this might change the grammar semantics)"
,
"-h print this help and exit"
,
"-i ignore redirects (don't discard redirected rules)"
,
"-k build case-insensitive keywords from single-letter fragments"
,
"-o <outputfile> specify the output file. default is stdout"
,
"-p strip inline comments and actions"
,
"-r verify the consistency of the symbol table"
,
"-s <startsymbol> specify the start rule of the grammar"
,
" (default: 1st rule of the 1st input file)"
,
"-t trace the grammar generation"
,
"-u make literals and classes case-insensitive"
,
"-v dump the symbol table"
);
map
{
print
$_
.
"\n"
; }
@helptext
;
exit
0;
}
sub
readFile
{
my
(
$infile
) =
@_
;
my
$inph
=
*STDIN
if
$infile
eq
'-'
;
open
(
$inph
,
"< $infile"
) ||
die
"can't open input file $infile : $!"
if
$infile
ne '-';
my
$file_text
=
do
{
local
$/;
<
$inph
>;
};
close
(
$inph
)
if
$infile
ne
'-'
;
return
$file_text
;
}
sub
processSymboltable
{
my
(
$self
,
$symboltable
,
$options
) =
@_
;
if
(
exists
$options
->{v} )
{
$Data::Dumper::Indent
= 1;
print
Dumper(
$symboltable
);
}
$symboltable
->setStartRule(
$options
->{s})
if
exists
$options
->{s};
$symboltable
->validateSymbolTable()
if
exists
$options
->{r};
my
$generator
= new MarpaX::G4::MarpaGen;
$generator
->stripallcomments
if
exists
$options
->{c};
$generator
->embedactions
if
exists
$options
->{e};
$generator
->fragment2class
if
exists
$options
->{f};
$generator
->shiftlazytogreedy
if
exists
$options
->{g};
$generator
->buildkeywords
if
exists
$options
->{k};
$generator
->stripactions
if
exists
$options
->{p};
$generator
->setVerbosity(2)
if
exists
$options
->{t};
$generator
->matchcaseinsensitive
if
exists
$options
->{u} ||
exists
$options
->{k};
my
$outputfile
=
'-'
;
$outputfile
=
$options
->{o}
if
exists
$options
->{o};
$generator
->setoutputfile(
$outputfile
);
$generator
->generate(
$symboltable
);
}
sub
translatestring
{
my
(
$self
,
$grammartext
,
$options
) =
@_
;
my
$parser
= new MarpaX::G4::Parser;
$parser
->enabletrace
if
exists
$options
->{t};
$parser
->ignoreredirect
if
exists
$options
->{i};
my
$symboltable
= new MarpaX::G4::Symboltable;
my
$data
=
$parser
->parse(
$grammartext
);
if
(
exists
$options
->{d} )
{
printf
"===\n=== Parsed Hashtable\n===\n"
;
$Data::Dumper::Indent
= 2;
print
Dumper(
$data
);
}
$symboltable
->importParseTree(
$data
);
$self
->processSymboltable(
$symboltable
,
$options
);
}
sub
translatefiles
{
my
(
$self
,
$inputfiles
,
$options
) =
@_
;
my
$parser
= new MarpaX::G4::Parser;
$parser
->enabletrace
if
exists
$options
->{t};
$parser
->ignoreredirect
if
exists
$options
->{i};
my
$symboltable
= new MarpaX::G4::Symboltable;
while
(
scalar
@$inputfiles
)
{
my
$infile
=
shift
@$inputfiles
;
my
$grammartext
= readFile(
$infile
);
my
$data
=
$parser
->parse(
$grammartext
);
if
(
exists
$options
->{d} )
{
$Data::Dumper::Indent
= 2;
print
Dumper(
$data
);
}
$symboltable
->importParseTree(
$data
);
}
$self
->processSymboltable(
$symboltable
,
$options
);
}
1;