#!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[]