package Parser;  ## no critic (RequireVersionVar)
use strict;
use warnings;
use utf8;
use 5.010;

use Marpa::R2 ();
use Carp ();

## no critic (RequireInitializationForLocalVars)
## no critic (ProhibitDoubleSigils)

use constant EXAMPLE_INPUT => <<'END';
If ((Myvalue.xyz == 1) Or (Frame_1.signal_1 == 1)) Then a = 1 Else a = 0;
END

sub parse {
    my ($self, $ref) = @_;
    state $grammar_source = do { local $/; scalar <DATA> };
    state $grammar = Marpa::R2::Scanless::G->new({
        bless_package => 'Ast',
        source => \$grammar_source,
    });
    my $recce = Marpa::R2::Scanless::R->new({ grammar => $grammar });
    $recce->read($ref);
    my $val = $recce->value // Carp::croak "No parse found";
    return $$val;
}

1;

__DATA__
:default    ::= action => [values]
:start      ::= StatementList
:discard    ~   ws

StatementList ::= Expression+ separator => SEMICOLON bless => Block

Expression ::=
        ('(') Expression (')')  assoc => group action => ::first
    |   NUMBER                  bless => Literal
    ||  IDENT                   bless => Var
    ||  Expression  ('==')  Expression  bless => Equals
    ||  Expression  ('=')   Expression  bless => Assign
    ||  Expression  ('Or')  Expression  bless => Or
    ||  Conditional  action => ::first

Conditional ::=
        ('If') Expression ('Then') Expression
            bless => Cond
    |   ('If') Expression ('Then') Expression ('Else') Expression
            bless => Cond

IDENT   ~ ident
NUMBER  ~ <number int> | <number rat>

word    ~ [\w]+
ident   ~ word | ident '.' word
<number int> ~ [\d]+
<number rat> ~ <number int> '.' <number int>
ws      ~ [\s]+
SEMICOLON ~ ';'
