#!perl
# Copyright 2013 Jeffrey Kegler
# This file is part of Marpa::R3. Marpa::R3 is free software: you can
# redistribute it and/or modify it under the terms of the GNU Lesser
# General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.
#
# Marpa::R3 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser
# General Public License along with Marpa::R3. If not, see
# http://www.gnu.org/licenses/.
# An ambiguous equation
use 5.010;
use strict;
use warnings;
use Test::More tests => 8;
use lib 'inc';
use Marpa::R3::Test;
use Data::Dumper;
use English qw( -no_match_vars );
use Fatal qw( close open );
use Marpa::R3;
# Regression test for bug originally found and documented
# by Tomas Jirotka
## INPUT DATA
my $tokens = [
[ 'CREATE', 'Create' ],
[ 'METRIC', 'Metric' ],
[ 'ID_METRIC', 'm' ],
[ 'AS', 'As' ],
[ 'SELECT', 'Select' ],
[ 'NUMBER', 1 ],
[ 'WHERE', 'Where' ],
[ 'TRUE', 'True' ],
];
my @terminals =
qw/AS BY CREATE FALSE FOR METRIC PF SELECT TRUE WHERE WITH ID_METRIC SEPARATOR NUMBER/;
my $grammar = Marpa::R3::Grammar->new(
{ start => 'Input',
action_object => 'Maql_Actions',
default_action => 'tisk',
default_empty_action => '::undef',
terminals => \@terminals,
rules => [
{ lhs => 'Input',
rhs => ['Statement'],
min => 1,
separator => 'SEPARATOR'
},
{ lhs => 'Statement',
rhs => [qw/CREATE TypeDef/],
},
{ lhs => 'TypeDef',
rhs => [qw/METRIC ID_METRIC AS MetricSelect/],
},
{ lhs => 'MetricSelect',
rhs => [qw/SELECT MetricExpr ByClause Match Filter WithPf/],
},
{ lhs => 'MetricExpr',
rhs => [qw/NUMBER/],
},
##############################################################################
{ lhs => 'ByClause',
rhs => [],
},
{ lhs => 'ByClause',
rhs => [qw/BY/],
},
##############################################################################
{ lhs => 'Match',
rhs => [],
},
{ lhs => 'Match',
rhs => [qw/FOR/],
},
#############################################################################
{ lhs => 'Filter',
rhs => [],
},
{ lhs => 'Filter',
rhs => [qw/WHERE FilterExpr/],
},
{ lhs => 'FilterExpr',
rhs => [qw/TRUE/],
},
{ lhs => 'FilterExpr',
rhs => [qw/FALSE/],
},
###############################################################################
{ lhs => 'WithPf',
rhs => [],
},
{ lhs => 'WithPf',
rhs => [qw/WITH PF/],
},
###############################################################################
],
}
);
$grammar->precompute();
Marpa::R3::Test::is(
$grammar->show_symbols(),
<<'END_OF_SYMBOLS', 'Symbols' );
0: AS, terminal
1: BY, terminal
2: CREATE, terminal
3: FALSE, terminal
4: FOR, terminal
5: METRIC, terminal
6: PF, terminal
7: SELECT, terminal
8: TRUE, terminal
9: WHERE, terminal
10: WITH, terminal
11: ID_METRIC, terminal
12: SEPARATOR, terminal
13: NUMBER, terminal
14: Input
15: Statement
16: TypeDef
17: MetricSelect
18: MetricExpr
19: ByClause
20: Match
21: Filter
22: WithPf
23: FilterExpr
END_OF_SYMBOLS
Marpa::R3::Test::is( $grammar->show_rules(),
<<'END_OF_RULES', 'Rules' );
0: Input -> Statement+ /* discard_sep */
1: Statement -> CREATE TypeDef
2: TypeDef -> METRIC ID_METRIC AS MetricSelect
3: MetricSelect -> SELECT MetricExpr ByClause Match Filter WithPf
4: MetricExpr -> NUMBER
5: ByClause -> /* empty !used */
6: ByClause -> BY
7: Match -> /* empty !used */
8: Match -> FOR
9: Filter -> /* empty !used */
10: Filter -> WHERE FilterExpr
11: FilterExpr -> TRUE
12: FilterExpr -> FALSE
13: WithPf -> /* empty !used */
14: WithPf -> WITH PF
END_OF_RULES
Marpa::R3::Test::is( $grammar->show_AHFA(),
<<'END_OF_AHFA', 'AHFA' );
* S0:
Input['] -> . Input
=> S2; leo(Input['])
* S1: predict
Input -> . Input[Seq]
Input -> . Input[Seq] SEPARATOR
Input[Seq] -> . Statement
Input[Seq] -> . Input[Seq] SEPARATOR Statement
Statement -> . CREATE TypeDef
=> S3; S4
=> S6
=> S5; leo(Input[Seq])
* S2: leo-c
Input['] -> Input .
* S3:
Statement -> CREATE . TypeDef
=> S7; leo(Statement)
* S4: predict
TypeDef -> . METRIC ID_METRIC AS MetricSelect
=> S8
* S5: leo-c
Input[Seq] -> Statement .
* S6:
Input -> Input[Seq] .
Input -> Input[Seq] . SEPARATOR
Input[Seq] -> Input[Seq] . SEPARATOR Statement
=> S10; S9
* S7: leo-c
Statement -> CREATE TypeDef .
* S8:
TypeDef -> METRIC . ID_METRIC AS MetricSelect
=> S11
* S9:
Input -> Input[Seq] SEPARATOR .
Input[Seq] -> Input[Seq] SEPARATOR . Statement
=> S12; leo(Input[Seq])
* S10: predict
Statement -> . CREATE TypeDef
=> S3; S4
* S11:
TypeDef -> METRIC ID_METRIC . AS MetricSelect
=> S13; S14
* S12: leo-c
Input[Seq] -> Input[Seq] SEPARATOR Statement .
* S13:
TypeDef -> METRIC ID_METRIC AS . MetricSelect
=> S15; leo(TypeDef)
* S14: predict
MetricSelect -> . SELECT MetricExpr ByClause MetricSelect[R3:3]
MetricSelect -> . SELECT MetricExpr ByClause Match[] Filter[] WithPf[]
MetricSelect -> . SELECT MetricExpr ByClause[] MetricSelect[R3:3]
MetricSelect -> . SELECT MetricExpr ByClause[] Match[] Filter[] WithPf[]