/usr/local/CPAN/yagg/yagg/NonterminalParser.pm
####################################################################
#
# This file was generated using Parse::Yapp version 1.05.
#
# Don't edit this file, use source file instead.
#
# ANY CHANGE MADE HERE WILL BE LOST !
#
####################################################################
package yagg::NonterminalParser;
use vars qw ( @ISA );
use strict;
@ISA= qw ( Parse::Yapp::Driver );
use Parse::Yapp::Driver;
#line 1 "etc/nonterminal_parser_grammar.yp"
# (c) Copyright David Coppit 2004, all rights reserved.
# (see COPYRIGHT in yagg documentation for use and distribution
# rights)
#
# Written by David Coppit <david@coppit.org>
#
# This grammar is based on that of Bison 1.05. I've left out undocumented
# features, and definitions that are unused. A version of this file was
# submitted to Francois Desarmenien, the author of Parse::Yapp. Hopefully he
# will decide to use it to update his grammar parser.
#
# Use: yapp -m 'yagg::NonterminalParser' -o lib/yagg/NonterminalParser.pm etc/nonterminal_parser_grammar.yp
#
# to generate the Parser module.
#
#line 19 "etc/nonterminal_parser_grammar.yp"
require 5.004;
use Carp;
my($input,$lexlevel,@lineno,$nberr,$prec,$precedences,$labelno);
my($syms,$declarations,$epilogue,$token,$term,$nterm,$rules,$precterm,$start,$nullable,$aliases);
my($expect);
sub new {
my($class)=shift;
ref($class)
and $class=ref($class);
my($self)=$class->SUPER::new( yyversion => '1.05',
yystates =>
[
{#State 0
DEFAULT => -3,
GOTOS => {
'input' => 1,
'declarations' => 2
}
},
{#State 1
ACTIONS => {
'' => 3
}
},
{#State 2
ACTIONS => {
'PERCENT_FILE_PREFIX' => 4,
'PERCENT_PARSE_PARAM' => 5,
'PERCENT_YACC' => 6,
'PERCENT_OUTPUT' => 8,
'PERCENT_DEFINES' => 9,
'PERCENT_LEFT' => 11,
'PERCENT_VERBOSE' => 12,
'PERCENT_DEBUG' => 13,
'PERCENT_PURE_PARSER' => 14,
'PERCENT_TOKEN_TABLE' => 17,
'SEMICOLON' => 16,
'PERCENT_TOKEN' => 15,
'PERCENT_TYPE' => 19,
'PERCENT_START' => 21,
"%%" => 22,
'PERCENT_LOCATIONS' => 23,
'PERCENT_UNION' => 24,
'PERCENT_NO_LINES' => 25,
'PERCENT_EXPECT' => 26,
'PERCENT_NAME_PREFIX' => 29,
'PROLOGUE' => 28,
'PERCENT_NONASSOC' => 30,
'PERCENT_RIGHT' => 31
},
GOTOS => {
'precedence_declaration' => 7,
'grammar_declaration' => 27,
'symbol_declaration' => 18,
'declaration' => 10,
'precedence_declarator' => 20
}
},
{#State 3
DEFAULT => 0
},
{#State 4
ACTIONS => {
'EQUAL' => 32
}
},
{#State 5
DEFAULT => -15
},
{#State 6
DEFAULT => -19
},
{#State 7
DEFAULT => -21
},
{#State 8
DEFAULT => -14
},
{#State 9
DEFAULT => -8
},
{#State 10
DEFAULT => -4
},
{#State 11
DEFAULT => -29
},
{#State 12
DEFAULT => -18
},
{#State 13
DEFAULT => -7
},
{#State 14
DEFAULT => -16
},
{#State 15
ACTIONS => {
'TYPE' => 36,
'IDENT' => 35
},
GOTOS => {
'ID' => 33,
'symbol_def' => 34,
'symbol_defs_1' => 37
}
},
{#State 16
DEFAULT => -20
},
{#State 17
DEFAULT => -17
},
{#State 18
DEFAULT => -22
},
{#State 19
ACTIONS => {
'TYPE' => 38
}
},
{#State 20
ACTIONS => {
'TYPE' => 40
},
DEFAULT => -32,
GOTOS => {
'type_opt' => 39
}
},
{#State 21
ACTIONS => {
'IDENT' => 35,
'STRING' => 42
},
GOTOS => {
'ID' => 41,
'symbol' => 44,
'string_as_id' => 43
}
},
{#State 22
ACTIONS => {
'ERROR' => 46,
'ID_COLON' => 48,
'SEMICOLON' => 47
},
DEFAULT => -2,
GOTOS => {
'grammar' => 49,
'rules_or_grammar_declaration' => 50,
'rules' => 45
}
},
{#State 23
DEFAULT => -11
},
{#State 24
ACTIONS => {
'BRACED_CODE' => 51
}
},
{#State 25
DEFAULT => -13
},
{#State 26
ACTIONS => {
'INT' => 52
}
},
{#State 27
DEFAULT => -5
},
{#State 28
DEFAULT => -6
},
{#State 29
ACTIONS => {
'EQUAL' => 53
}
},
{#State 30
DEFAULT => -31
},
{#State 31
DEFAULT => -30
},
{#State 32
ACTIONS => {
'STRING' => 54
},
GOTOS => {
'string_content' => 55
}
},
{#State 33
ACTIONS => {
'STRING' => 42,
'INT' => 57
},
DEFAULT => -36,
GOTOS => {
'string_as_id' => 56
}
},
{#State 34
DEFAULT => -40
},
{#State 35
DEFAULT => -64
},
{#State 36
ACTIONS => {
'IDENT' => 35
},
GOTOS => {
'ID' => 33,
'symbol_def' => 34,
'symbol_defs_1' => 58
}
},
{#State 37
ACTIONS => {
'IDENT' => 35
},
DEFAULT => -25,
GOTOS => {
'ID' => 33,
'symbol_def' => 59
}
},
{#State 38
ACTIONS => {
'IDENT' => 35,
'STRING' => 42
},
GOTOS => {
'ID' => 41,
'symbols_1' => 61,
'symbol' => 60,
'string_as_id' => 43
}
},
{#State 39
ACTIONS => {
'IDENT' => 35,
'STRING' => 42
},
GOTOS => {
'ID' => 41,
'symbols_1' => 62,
'symbol' => 60,
'string_as_id' => 43
}
},
{#State 40
DEFAULT => -33
},
{#State 41
DEFAULT => -55
},
{#State 42
DEFAULT => -60
},
{#State 43
DEFAULT => -56
},
{#State 44
DEFAULT => -23
},
{#State 45
DEFAULT => -44
},
{#State 46
ACTIONS => {
'IDENT' => 35,
'SEMICOLON' => 63,
'STRING' => 42
},
GOTOS => {
'ID' => 41,
'symbol' => 64,
'string_as_id' => 43
}
},
{#State 47
DEFAULT => -47
},
{#State 48
DEFAULT => -51,
GOTOS => {
'rhses_1' => 66,
'rhs' => 65
}
},
{#State 49
ACTIONS => {
'ERROR' => 46,
'ID_COLON' => 48,
"%%" => 67,
'SEMICOLON' => 47
},
DEFAULT => -62,
GOTOS => {
'rules_or_grammar_declaration' => 69,
'rules' => 45,
'epilogue_opt' => 68
}
},
{#State 50
DEFAULT => -42
},
{#State 51
DEFAULT => -24
},
{#State 52
DEFAULT => -9
},
{#State 53
ACTIONS => {
'STRING' => 54
},
GOTOS => {
'string_content' => 70
}
},
{#State 54
DEFAULT => -61
},
{#State 55
DEFAULT => -10
},
{#State 56
DEFAULT => -38
},
{#State 57
ACTIONS => {
'STRING' => 42
},
DEFAULT => -37,
GOTOS => {
'string_as_id' => 71
}
},
{#State 58
ACTIONS => {
'IDENT' => 35
},
DEFAULT => -26,
GOTOS => {
'ID' => 33,
'symbol_def' => 59
}
},
{#State 59
DEFAULT => -41
},
{#State 60
DEFAULT => -34
},
{#State 61
ACTIONS => {
'IDENT' => 35,
'STRING' => 42
},
DEFAULT => -27,
GOTOS => {
'ID' => 41,
'symbol' => 72,
'string_as_id' => 43
}
},
{#State 62
ACTIONS => {
'IDENT' => 35,
'STRING' => 42
},
DEFAULT => -28,
GOTOS => {
'ID' => 41,
'symbol' => 72,
'string_as_id' => 43
}
},
{#State 63
DEFAULT => -46
},
{#State 64
ACTIONS => {
'SEMICOLON' => 73
}
},
{#State 65
ACTIONS => {
'IDENT' => 35,
'BRACED_CODE' => -57,
'PERCENT_PREC' => 75,
'STRING' => 42,
'BRACED_CODE_WITH_BRACED_CODE_FOLLOWING' => 77
},
DEFAULT => -49,
GOTOS => {
'ID' => 41,
'symbol' => 76,
'action_opt' => 74,
'string_as_id' => 43
}
},
{#State 66
ACTIONS => {
'PIPE' => 78
},
DEFAULT => -48
},
{#State 67
ACTIONS => {
'EPILOGUE' => 79
}
},
{#State 68
DEFAULT => -1
},
{#State 69
DEFAULT => -43
},
{#State 70
DEFAULT => -12
},
{#State 71
DEFAULT => -39
},
{#State 72
DEFAULT => -35
},
{#State 73
DEFAULT => -45
},
{#State 74
ACTIONS => {
'BRACED_CODE' => 80
},
GOTOS => {
'action' => 81
}
},
{#State 75
ACTIONS => {
'IDENT' => 35,
'STRING' => 42
},
GOTOS => {
'ID' => 41,
'symbol' => 82,
'string_as_id' => 43
}
},
{#State 76
DEFAULT => -52
},
{#State 77
DEFAULT => -58
},
{#State 78
DEFAULT => -51,
GOTOS => {
'rhs' => 83
}
},
{#State 79
DEFAULT => -63
},
{#State 80
DEFAULT => -59
},
{#State 81
DEFAULT => -53
},
{#State 82
DEFAULT => -54
},
{#State 83
ACTIONS => {
'IDENT' => 35,
'BRACED_CODE' => -57,
'PERCENT_PREC' => 75,
'STRING' => 42,
'BRACED_CODE_WITH_BRACED_CODE_FOLLOWING' => 77
},
DEFAULT => -50,
GOTOS => {
'ID' => 41,
'symbol' => 76,
'action_opt' => 74,
'string_as_id' => 43
}
}
],
yyrules =>
[
[#Rule 0
'$start', 2, undef
],
[#Rule 1
'input', 4,
sub
#line 74 "etc/nonterminal_parser_grammar.yp"
{
$start
or $start=$$rules[1][0];
ref($$nterm{$start})
or _SyntaxError(2,"Start symbol $start not found ".
"in rules section",$_[4][1]);
$$rules[0]=[ '$start', [ $start, chr(0) ], undef, undef ];
}
],
[#Rule 2
'input', 2,
sub
#line 85 "etc/nonterminal_parser_grammar.yp"
{ _SyntaxError(2,"No rules in input grammar",$_[2][1]); }
],
[#Rule 3
'declarations', 0, undef
],
[#Rule 4
'declarations', 2, undef
],
[#Rule 5
'declaration', 1, undef
],
[#Rule 6
'declaration', 1,
sub
#line 100 "etc/nonterminal_parser_grammar.yp"
{ push(@$declarations,$_[1]); undef }
],
[#Rule 7
'declaration', 1,
sub
#line 101 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%debug\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 8
'declaration', 1,
sub
#line 105 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%defines\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 9
'declaration', 2,
sub
#line 109 "etc/nonterminal_parser_grammar.yp"
{ $expect=$_[2][0]; undef }
],
[#Rule 10
'declaration', 3,
sub
#line 110 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%file-prefix\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 11
'declaration', 1,
sub
#line 114 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%locations\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 12
'declaration', 3,
sub
#line 118 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%name-prefix\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 13
'declaration', 1,
sub
#line 122 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%no-lines\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 14
'declaration', 1,
sub
#line 126 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%output\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 15
'declaration', 1,
sub
#line 130 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%parse-param\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 16
'declaration', 1,
sub
#line 134 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%pure-parser\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 17
'declaration', 1,
sub
#line 138 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%token-table\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 18
'declaration', 1,
sub
#line 142 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%verbose\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 19
'declaration', 1,
sub
#line 146 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"Parser option \"\%yacc\" is not supported. ".
"It will be ignored",$_[1][1]);
}
],
[#Rule 20
'declaration', 1, undef
],
[#Rule 21
'grammar_declaration', 1, undef
],
[#Rule 22
'grammar_declaration', 1, undef
],
[#Rule 23
'grammar_declaration', 2,
sub
#line 157 "etc/nonterminal_parser_grammar.yp"
{
$start=$_[2][0]; undef
}
],
[#Rule 24
'grammar_declaration', 2,
sub
#line 161 "etc/nonterminal_parser_grammar.yp"
{
undef
}
],
[#Rule 25
'symbol_declaration', 2,
sub
#line 168 "etc/nonterminal_parser_grammar.yp"
{
for (@{$_[2]}) {
my($symbol,$lineno)=@$_;
exists($$token{$symbol})
and do {
_SyntaxError(0,
"Token $symbol redefined: ".
"Previously defined line $$token{$symbol}",
$lineno);
next;
};
$$token{$symbol}=$lineno;
$$term{$symbol} = [ ];
}
undef
}
],
[#Rule 26
'symbol_declaration', 3,
sub
#line 186 "etc/nonterminal_parser_grammar.yp"
{
for (@{$_[3]}) {
my($symbol,$lineno)=@$_;
exists($$token{$symbol})
and do {
_SyntaxError(0,
"Token $symbol redefined: ".
"Previously defined line $$token{$symbol}",
$lineno);
next;
};
$$token{$symbol}=$lineno;
$$term{$symbol} = [ ];
}
undef
}
],
[#Rule 27
'symbol_declaration', 3,
sub
#line 204 "etc/nonterminal_parser_grammar.yp"
{
for ( @{$_[3]} ) {
my($symbol,$lineno)=@$_;
exists($$nterm{$symbol})
and do {
_SyntaxError(0,
"Non-terminal $symbol redefined: ".
"Previously defined line $$nterm{$symbol}",
$lineno);
next;
};
delete($$term{$symbol}); #not a terminal
$$nterm{$symbol}=undef; #is a non-terminal
}
}
],
[#Rule 28
'precedence_declaration', 3,
sub
#line 224 "etc/nonterminal_parser_grammar.yp"
{
for (@{$_[3]}) {
my($symbol,$lineno)=@$_;
defined($$precedences{$symbol})
and do {
_SyntaxError(1,
"Precedence for symbol $symbol redefined: ".
"Previously defined line $$precedences{$symbol}",
$lineno);
next;
};
$$token{$symbol}=$lineno;
$$term{$symbol} = [ $_[1][0], $prec ];
$$precedences{$symbol} = $prec;
}
++$prec;
undef
}
],
[#Rule 29
'precedence_declarator', 1, undef
],
[#Rule 30
'precedence_declarator', 1, undef
],
[#Rule 31
'precedence_declarator', 1, undef
],
[#Rule 32
'type_opt', 0, undef
],
[#Rule 33
'type_opt', 1, undef
],
[#Rule 34
'symbols_1', 1,
sub
#line 259 "etc/nonterminal_parser_grammar.yp"
{ [ $_[1] ] }
],
[#Rule 35
'symbols_1', 2,
sub
#line 260 "etc/nonterminal_parser_grammar.yp"
{ push(@{$_[1]},$_[2]); $_[1] }
],
[#Rule 36
'symbol_def', 1, undef
],
[#Rule 37
'symbol_def', 2,
sub
#line 267 "etc/nonterminal_parser_grammar.yp"
{
_SyntaxError(0,"User-defined numeric token codes are not supported. ".
"The value \"$_[2][0]\" will be ignored",$_[2][1]);
$_[1];
}
],
[#Rule 38
'symbol_def', 2,
sub
#line 273 "etc/nonterminal_parser_grammar.yp"
{
$$aliases{$_[2][0]} = $_[1][0];
delete $$term{$_[2][0]};
$_[1];
}
],
[#Rule 39
'symbol_def', 3,
sub
#line 279 "etc/nonterminal_parser_grammar.yp"
{
$$aliases{$_[3][0]} = $_[1][0];
delete $$term{$_[3][0]};
_SyntaxError(0,"User-defined numeric token codes are not supported. ".
"The value \"$_[2][0]\" will be ignored",$_[2][1]);
$_[1];
}
],
[#Rule 40
'symbol_defs_1', 1,
sub
#line 291 "etc/nonterminal_parser_grammar.yp"
{ [ $_[1] ] }
],
[#Rule 41
'symbol_defs_1', 2,
sub
#line 293 "etc/nonterminal_parser_grammar.yp"
{ push(@{$_[1]},$_[2]); $_[1]; }
],
[#Rule 42
'grammar', 1, undef
],
[#Rule 43
'grammar', 2, undef
],
[#Rule 44
'rules_or_grammar_declaration', 1, undef
],
[#Rule 45
'rules_or_grammar_declaration', 3,
sub
#line 318 "etc/nonterminal_parser_grammar.yp"
{
$_[0]->YYErrok
}
],
[#Rule 46
'rules_or_grammar_declaration', 2,
sub
#line 322 "etc/nonterminal_parser_grammar.yp"
{
$_[0]->YYErrok
}
],
[#Rule 47
'rules_or_grammar_declaration', 1, undef
],
[#Rule 48
'rules', 2,
sub
#line 330 "etc/nonterminal_parser_grammar.yp"
{
# For some reason Parse::Yapp treats the last code array as a
# non-reference. i.e. instead of
# [ ['SYMB',...], ['BRACED_CODE',...], ['SYMB',...], ['BRACED_CODE',['x',4]] ]
# it has
# [ ['SYMB',...], ['BRACED_CODE',...], ['SYMB',...], 'x',4 ]
my $code;
for(my $i=0;$i<=$#{$_[2]};$i++)
{
unless (defined $_[2][$i])
{
splice(@{$_[2]},$i,1,[undef,undef]);
next;
}
# Get the precedence, if any
my $precedence = undef;
for(my $j=0;$j<=$#{$_[2][$i]};$j++)
{
if ($_[2][$i][$j][0] eq 'PERCENT_PREC')
{
if(defined $precedence)
{
_SyntaxError(2,"\%prec can only appear once in a rule", $_[1][1]);
}
else
{
$precedence = $_[2][$i][$j][1];
splice(@{$_[2][$i]},$j,1),
}
}
}
# Dereference last code block
my $code_block_found = 0;
if(@{$_[2][$i]} >= 1)
{
if ($_[2][$i][-1][0] eq 'BRACED_CODE')
{
$code_block_found = 1;
# Merge the lists if there was an unaction block too. (We
# need to make sure we do this in a way that doesn't freak
# Parse::Yapp out.)
my @code_and_line_numbers = @{ $_[2][$i][-1][1] };
push @code_and_line_numbers, @{ $_[2][$i][-1][2] }
if defined $_[2][$i][-1][2];
splice(@{$_[2][$i]},-1,1,($precedence,\@code_and_line_numbers));
}
}
# Append undef, undef if no code block was found
push @{$_[2][$i]}, $precedence, undef unless $code_block_found;
for(my $j=0;$j<=$#{$_[2][$i]}-2;$j++)
{
$_[2][$i][$j][0] = 'CODE' if $_[2][$i][$j][0] eq 'BRACED_CODE';
}
}
_AddRules($_[1],$_[2]);
undef;
}
],
[#Rule 49
'rhses_1', 1,
sub
#line 399 "etc/nonterminal_parser_grammar.yp"
{ [ $_[1] ] }
],
[#Rule 50
'rhses_1', 3,
sub
#line 400 "etc/nonterminal_parser_grammar.yp"
{ push(@{$_[1]},$_[3]); $_[1] }
],
[#Rule 51
'rhs', 0,
sub
#line 405 "etc/nonterminal_parser_grammar.yp"
{ }
],
[#Rule 52
'rhs', 2,
sub
#line 407 "etc/nonterminal_parser_grammar.yp"
{
push(@{$_[1]},[ 'SYMB', $_[2] ]);
$_[1];
}
],
[#Rule 53
'rhs', 3,
sub
#line 412 "etc/nonterminal_parser_grammar.yp"
{
if (defined $_[2])
{
push(@{$_[1]}, [ 'BRACED_CODE', $_[2], $_[3] ] );
}
else
{
push(@{$_[1]}, [ 'BRACED_CODE', $_[3] ] );
}
$_[1];
}
],
[#Rule 54
'rhs', 3,
sub
#line 424 "etc/nonterminal_parser_grammar.yp"
{
defined($$precedences{$_[3][0]})
or do {
_SyntaxError(1,"No precedence for symbol $_[3][0]",
$_[3][1]);
return undef;
};
++$$precterm{$_[3][0]};
my $temp = $$precedences{$_[3][0]};
push(@{$_[1]}, [ 'PERCENT_PREC', $temp ] );
$_[1];
}
],
[#Rule 55
'symbol', 1, undef
],
[#Rule 56
'symbol', 1,
sub
#line 443 "etc/nonterminal_parser_grammar.yp"
{
if (exists $$aliases{$_[1][0]})
{
$_[1][0] = $$aliases{$_[1][0]};
}
else
{
# Must be a literal, in which case we don't touch it.
}
$_[1];
}
],
[#Rule 57
'action_opt', 0, undef
],
[#Rule 58
'action_opt', 1, undef
],
[#Rule 59
'action', 1, undef
],
[#Rule 60
'string_as_id', 1,
sub
#line 468 "etc/nonterminal_parser_grammar.yp"
{
if (exists $$aliases{$_[1][0]})
{
exists($$syms{$$aliases{$_[1][0]}})
or do {
$$syms{$$aliases{$_[1][0]}} = $_[1][1];
$$term{$$aliases{$_[1][0]}} = undef;
};
}
else
{
exists($$syms{$_[1][0]})
or do {
$$syms{$_[1][0]} = $_[1][1];
$$term{$_[1][0]} = undef;
};
}
$_[1]
}
],
[#Rule 61
'string_content', 1,
sub
#line 492 "etc/nonterminal_parser_grammar.yp"
{
$_[1][0] =~ s/.(.*)./$1/;
$_[1]
}
],
[#Rule 62
'epilogue_opt', 0, undef
],
[#Rule 63
'epilogue_opt', 2,
sub
#line 501 "etc/nonterminal_parser_grammar.yp"
{
$epilogue=$_[2]
}
],
[#Rule 64
'ID', 1,
sub
#line 506 "etc/nonterminal_parser_grammar.yp"
{
exists($$syms{$_[1][0]})
or do {
$$syms{$_[1][0]} = $_[1][1];
$$term{$_[1][0]} = undef;
};
$_[1]
}
]
],
@_);
bless($self,$class);
}
#line 516 "etc/nonterminal_parser_grammar.yp"
sub _Error {
my($value)=$_[0]->YYCurval;
my($what)= $token ? "input: '$$value[0]'" : "end of input";
_SyntaxError(1,"Unexpected $what",$$value[1]);
}
sub _Lexer {
#At EOF
pos($$input) >= length($$input)
and return('',[ undef, -1 ]);
#In Epilogue section
$lexlevel > 1
and do {
my($pos)=pos($$input);
$lineno[0]=$lineno[1];
$lineno[1]=-1;
pos($$input)=length($$input);
return('EPILOGUE',[ substr($$input,$pos), $lineno[0] ]);
};
#Skip blanks
$$input=~m{\G((?:
\s+ # any white space char
| \#[^\n]*\n # Perl like comments
| /\*.*?\*/ # C like comments
| //[^\n]*\n # C++ like comments
)+)}xsgc
and do {
my($blanks)=$1;
#Maybe At EOF
pos($$input) >= length($$input)
and return('',[ undef, -1 ]);
$lineno[1]+= $blanks=~tr/\n//;
};
$lineno[0]=$lineno[1];
$$input=~/\G<([A-Za-z_.][A-Za-z0-9_.]*)>/gc
and return('TYPE',[ $1, $lineno[0] ]);
$$input=~m{\G
([A-Za-z_.][A-Za-z0-9_.]*) #identifier
((?:
\s+ # any white space char
| \#[^\n]*\n # Perl like comments
| /\*.*?\*/ # C like comments
| //[^\n]*\n # C++ like comments
)*)
: # colon
}xsgc
and do {
my($blanks)=$2;
$lineno[1]+= $blanks=~tr/\n//;
return('ID_COLON',[ $1, $lineno[0] ]);
};
$$input=~/\G([A-Za-z_.][A-Za-z0-9_.]*)/gc
and do {
$1 eq 'error'
and do {
return('ERROR',[ 'error', $lineno[0] ]);
};
return('IDENT',[ $1, $lineno[0] ]);
};
$$input=~/\G('(?:[^'\\]|\\\\|\\'|\\)+?')/gc
and do {
$1 eq "'error'"
and do {
_SyntaxError(0,"Literal 'error' ".
"will be treated as error token",$lineno[0]);
return('ERROR',[ 'error', $lineno[0] ]);
};
return('STRING',[ $1, $lineno[0] ]);
};
$$input=~/\G("(?:[^"\\]|\\\\|\\"|\\)+?")/gc
and do {
$1 eq '"error"'
and do {
_SyntaxError(0,'Literal "error" '.
"will be treated as error token",$lineno[0]);
return('ERROR',[ 'error', $lineno[0] ]);
};
return('STRING',[ $1, $lineno[0] ]);
};
$$input=~/\G(%%)/gc
and do {
++$lexlevel;
return($1, [ $1, $lineno[0] ]);
};
$$input=~/\G{/gc
and do {
my $code;
my $level = 1;
my $from=pos($$input);
my $to;
while($$input =~ /\G(.*?
(?:
\#[^\n]*\n # Perl like comments
| \/\*.*?\*\/ # C like comments
| \/\/[^\n]*\n # C++ like comments
| (?<!\\)'.*?(?<!\\)' # Single-quoted strings
| (?<!\\)".*?(?<!\\)" # Double-quoted strings
| ([{}]|$) # Our match or EOF
)
)/xsgc)
{
if (defined $2)
{
if ($2 eq '}')
{
$level--;
unless($level)
{
$to = pos($$input) - 1;
last;
}
}
elsif ($2 eq '{')
{
$level++;
}
else
{
$to = length $$input;
print(2,"Unmatched { opened line $lineno[0]",-1);
last;
}
}
}
$code = substr($$input,$from,$to-$from);
$lineno[1]+= $code=~tr/\n//;
# Lookahead to resolve shift/reduce error
{
my $old_pos = pos $$input;
if ($$input =~ /\G\s*{/)
{
pos $$input = $old_pos;
return('BRACED_CODE_WITH_BRACED_CODE_FOLLOWING',[ $code, $lineno[0] ]);
}
else
{
pos $$input = $old_pos;
return('BRACED_CODE',[ $code, $lineno[0] ]);
}
}
};
if($lexlevel == 0) {# In declarations section
$$input=~/\G%left/gc
and return('PERCENT_LEFT',[ 'LEFT', $lineno[0] ]);
$$input=~/\G%right/gc
and return('PERCENT_RIGHT',[ 'RIGHT', $lineno[0] ]);
$$input=~/\G%nonassoc/gc
and return('PERCENT_NONASSOC',[ 'NONASSOC', $lineno[0] ]);
$$input=~/\G%(start)/gc
and return('PERCENT_START',[ undef, $lineno[0] ]);
$$input=~/\G%(expect)/gc
and return('PERCENT_EXPECT',[ undef, $lineno[0] ]);
$$input=~/\G%{/gc
and do {
my($code);
my $from=pos($$input);
my $to;
while($$input =~ m{\G(.*?
(?:
\#[^\n]*\n # Perl like comments
| /\*.*?\*/ # C like comments
| //[^\n]*\n # C++ like comments
| (%\}|$) # Our match or EOF
)
)}xsgc)
{
if (defined $2)
{
if ($2 eq '%}')
{
$to = pos($$input) - 2;
}
else
{
$to = length $$input;
_SyntaxError(2,"Unmatched \%{ opened line $lineno[0]",-1)
}
last;
}
}
$code = substr($$input,$from,$to-$from);
$lineno[1]+= $code=~tr/\n//;
return('PROLOGUE',[ $code, $lineno[0] ]);
};
$$input=~/\G%(token)/gc
and return('PERCENT_TOKEN',[ undef, $lineno[0] ]);
$$input=~/\G%(type)/gc
and return('PERCENT_TYPE',[ undef, $lineno[0] ]);
$$input=~/\G%(union)/gc
and return('PERCENT_UNION',[ undef, $lineno[0] ]);
$$input=~/\G%(debug)/gc
and return('PERCENT_DEBUG',[ undef, $lineno[0] ]);
$$input=~/\G%(defines)/gc
and return('PERCENT_DEFINES',[ undef, $lineno[0] ]);
$$input=~/\G%(file-prefix)/gc
and return('PERCENT_FILE_PREFIX',[ undef, $lineno[0] ]);
$$input=~/\G%(locations)/gc
and return('PERCENT_LOCATIONS',[ undef, $lineno[0] ]);
$$input=~/\G%(name-prefix)/gc
and return('PERCENT_NAME_PREFIX',[ undef, $lineno[0] ]);
$$input=~/\G%(no-lines)/gc
and return('PERCENT_NO_LINES',[ undef, $lineno[0] ]);
$$input=~/\G%(output)/gc
and return('PERCENT_OUTPUT',[ undef, $lineno[0] ]);
$$input=~/\G%(parse-param)/gc
and return('PERCENT_PARSE_PARAM',[ undef, $lineno[0] ]);
$$input=~/\G%(pure[-_]parser)/gc
and return('PERCENT_PURE_PARSER',[ undef, $lineno[0] ]);
$$input=~/\G%(token-table)/gc
and return('PERCENT_TOKEN_TABLE',[ undef, $lineno[0] ]);
$$input=~/\G%(verbose)/gc
and return('PERCENT_VERBOSE',[ undef, $lineno[0] ]);
$$input=~/\G%(yacc)/gc
and return('PERCENT_YACC',[ undef, $lineno[0] ]);
$$input=~/\G([0-9]+)/gc
and return('INT',[ $1, $lineno[0] ]);
}
else {# In rule section
$$input=~/\G%(prec)/gc
and return('PERCENT_PREC',[ undef, $lineno[0] ]);
}
$$input=~/\G=/gc
and return('EQUAL',[ undef, $lineno[0] ]);
$$input=~/\G;/gc
and return('SEMICOLON',[ undef, $lineno[0] ]);
$$input=~/\G\|/gc
and return('PIPE',[ undef, $lineno[0] ]);
#Always return something
$$input=~/\G(.)/sg
or die "Parse::Yapp::Grammar::Parse: Match (.) failed: report as a BUG";
$1 eq "\n"
and ++$lineno[1];
( $1 ,[ $1, $lineno[0] ]);
}
sub _SyntaxError {
my($level,$message,$lineno)=@_;
$message= "*".
[ 'Warning', 'Error', 'Fatal' ]->[$level].
"* $message, at ".
($lineno < 0 ? "eof" : "line $lineno").
".\n";
$level > 1
and die $message;
warn $message;
$level > 0
and ++$nberr;
$nberr == 20
and die "*Fatal* Too many errors detected.\n"
}
sub _AddRules {
my($lhs,$lineno)=@{$_[0]};
my($rhss)=$_[1];
ref($$nterm{$lhs})
and do {
_SyntaxError(1,"Non-terminal $lhs redefined: ".
"Previously declared line $$syms{$lhs}",$lineno);
return;
};
ref($$term{$lhs})
and do {
my($where) = exists($$token{$lhs}) ? $$token{$lhs} : $$syms{$lhs};
_SyntaxError(1,"Non-terminal $lhs previously ".
"declared as token line $where",$lineno);
return;
};
ref($$nterm{$lhs}) #declared through %type
or do {
$$syms{$lhs}=$lineno; #Say it's declared here
delete($$term{$lhs}); #No more a terminal
};
$$nterm{$lhs}=[]; #It's a non-terminal now
my($epsrules)=0; #To issue a warning if more than one epsilon rule
for my $rhs (@$rhss) {
my($tmprule)=[ $lhs, [ ], splice(@$rhs,-2) ]; #Init rule
@$rhs
or do {
++$$nullable{$lhs};
++$epsrules;
};
for (0..$#$rhs) {
my($what,$value)=@{$$rhs[$_]};
$what eq 'CODE'
and do {
my($name)='@'.++$labelno."-$_";
push(@$rules,[ $name, [], undef, $value ]);
push(@{$$tmprule[1]},$name);
next;
};
push(@{$$tmprule[1]},$$value[0]);
}
push(@$rules,$tmprule);
push(@{$$nterm{$lhs}},$#$rules);
}
$epsrules > 1
and _SyntaxError(0,"More than one empty rule for symbol $lhs",$lineno);
}
sub Parse {
my($self)=shift;
@_ > 0
or croak("No input grammar\n");
my($parsed)={};
$input=\$_[0];
$lexlevel=0;
@lineno=(1,1);
$nberr=0;
$prec=0;
$labelno=0;
$declarations=();
$epilogue="";
$syms={};
$token={};
$term={};
$precedences={};
$nterm={};
$rules=[ undef ]; #reserve slot 0 for start rule
$precterm={};
$start="";
$nullable={};
$aliases={};
$expect=0;
pos($$input)=0;
$self->YYParse(yylex => \&_Lexer, yyerror => \&_Error);
$nberr
and _SyntaxError(2,"Errors detected: No output",-1);
@$parsed{ 'HEAD', 'TAIL', 'RULES', 'NTERM', 'TERM',
'NULL', 'PREC', 'SYMS', 'START', 'EXPECT' }
= ( $declarations, $epilogue, $rules, $nterm, $term,
$nullable, $precterm, $syms, $start, $expect);
undef($input);
undef($lexlevel);
undef(@lineno);
undef($nberr);
undef($prec);
undef($labelno);
undef($declarations);
undef($epilogue);
undef($syms);
undef($token);
undef($term);
undef($precedences);
undef($nterm);
undef($rules);
undef($precterm);
undef($start);
undef($nullable);
undef($aliases);
undef($expect);
$parsed
}
1;