=pod

=encoding utf8

=head1 NAME

Language::MuldisD::Grammar -
How to format Concrete Muldis D

=head1 VERSION

This document is Language::MuldisD::Grammar version 0.6.1.

=head1 PREFACE

This document is part of the Muldis D language specification, whose root
document is L<Language::MuldisD>; you should read that root document
before you read this one, which provides subservient details.

=head1 DESCRIPTION

This document outlines the grammar of I<Concrete Muldis D>.  This grammar
is extremely simple such that any program or routine is simply a tuple
literal, which is composed of relation and tuple and scalar literals.
Whether or not these literals are valid is up to the I<Abstract Muldis D>
compiler, whose input is the AST resulting from parsing I<Concrete Muldis
D>.  This grammar primarily tests for well-formedness.

See also, for example, L<Language::MuldisD::PerlHosted> for a description
of the core Perl data structures that you would probably use instead of the
grammar below when using a Muldis D implementation in a Perl application.

I<This documentation is pending.>

=head1 GRAMMAR OF CONCRETE MULDIS D

This grammar is formatted as a Perl 6 grammar which could be used to parse
it.  That said, it is only meant to be illustrative, as only some Muldis D
implementations would actually be written in Perl 6 or understand Perl 6
grammars.  The following Perl 6 code does successfully compile using the
current Perl6::Pugs, though it has not yet been tested to execute
correctly.  Any remaining errors should be corrected as soon as possible.

    use v6-alpha;

    # grammar MuldisD:ver<0.6.1>:auth<cpan:DUNCAND>;
    grammar MuldisD-0.6.1-cpan:DUNCAND;

    token start {
        (MuldisD)
        <spec_sep>
        <version_and_authority>
        <spec_sep>
        <list_open>
            (<literal>)
        <list_close>
    }

    token version_and_authority { <quoted_text_str> }

    token literal {
          <bool>
        | <order>
        | <int>
        | <rat>
        | <blob>
        | <text>
        | <tuple>
        | <relation>
        | <cat_short_name>
        | <cat_long_name>
    }

    token bool { (Bool) <spec_sep> (false|true) }

    token order { (Order) <spec_sep> (increase|same|decrease) }

    token int {
          <just_an_int>
        | <uint>
        | <pint>
    }

    token just_an_int {
        (Int)
        <spec_sep>
        (<[1-9A-Z]>)
        <spec_sep>
        (0|\-?<[1-9A-Z]><[0-9A-Z]>*)
    }

    token uint {
        (UInt)
        <spec_sep>
        (<[1-9A-Z]>)
        <spec_sep>
        (0|<[1-9A-Z]><[0-9A-Z]>*)
    }

    token pint {
        (PInt)
        <spec_sep>
        (<[1-9A-Z]>)
        <spec_sep>
        (<[1-9A-Z]><[0-9A-Z]>*)
    }

    token rat {
          <just_an_rat>
        | <urat>
        | <prat>
    }

    token just_an_rat {
        (Rat)
        <spec_sep>
        (<[1-9A-Z]>)
        <spec_sep>
        (0|\-?<[1-9A-Z]><[0-9A-Z]>*\.?<[0-9A-Z]>*)
    }

    token urat {
        (URat)
        <spec_sep>
        (<[1-9A-Z]>)
        <spec_sep>
        (0|<[1-9A-Z]><[0-9A-Z]>*\.?<[0-9A-Z]>*)
    }

    token prat {
        (PRat)
        <spec_sep>
        (<[1-9A-Z]>)
        <spec_sep>
        (<[1-9A-Z]><[0-9A-Z]>*\.?<[0-9A-Z]>*)
    }

    token blob {
          <just_a_blob>
        | <ne_blob>
    }

    token just_a_blob {
        (Blob)
        <spec_sep>
        (<[137F]>)
        <spec_sep>
        (<[0-9A-F]>*)
    }

    token ne_blob {
        (NEBlob)
        <spec_sep>
        (<[137F]>)
        <spec_sep>
        (<[0-9A-F]>+)
    }

    token text {
          <just_a_text>
        | <ne_text>
    }

    token just_a_text {
        (Text)
        <spec_sep>
        <quoted_text_str>
    }

    token ne_text {
        (NEText)
        <spec_sep>
        <quoted_ne_text_str>
    }

    token tuple {
          <just_a_tuple>
        | <database>
    }

    token just_a_tuple {
        (Tuple)
        <spec_sep>
        <type_name>
        <spec_sep>
        <tuple_body>
    }

    token database {
        (Database)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<relation_typed_attr>) <list_sep>)*)
        <list_close>
    }

    token relation_typed_attr { <attr_name> <pair_sep> <relation> }

    token relation {
          <just_a_relation>
        | <set>
        | <maybe>
        | <seq>
        | <bag>
    }

    token just_a_relation {
        (Relation)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<tuple_body>) <list_sep>)*)
        <list_close>
    }

    token tuple_body {
        <list_open>
            (((<attr>) <list_sep>)*)
        <list_close>
    }

    token attr { <attr_name> <pair_sep> <literal> }

    token attr_name { <quoted_text_str> }

    token set {
        (Set)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<literal>) <list_sep>)*)
        <list_close>
    }

    token maybe {
        (Maybe)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (<literal>?)
        <list_close>
    }

    token seq {
          seq_indexed_values
        | seq_ordered_values
    }

    token seq_indexed_values {
        (Seq)
        <spec_sep>
        (index)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<index>) <pair_sep> (<literal>) <list_sep>)*)
        <list_close>
    }

    token index { <uint> }

    token seq_ordered_values {
        (Seq)
        <spec_sep>
        (order)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<literal>) <list_sep>)*)
        <list_close>
    }

    token bag {
          bag_counted_values
        | bag_repeated_values
    }

    token bag_counted_values {
        (Bag)
        <spec_sep>
        (count)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<literal>) <pair_sep> (<count>) <list_sep>)*)
        <list_close>
    }

    token count { <pint> }

    token bag_repeated_values {
        (Bag)
        <spec_sep>
        (repeat)
        <spec_sep>
        <type_name>
        <spec_sep>
        <list_open>
            (((<literal>) <list_sep>)*)
        <list_close>
    }

    token list_open { '{' \s+ }

    token list_close { \s+ '}' }

    token list_sep { ',' \s+ }

    token pair_sep { \s+ '=>' \s+ }

    token type_name { <quoted_text_str> }

    token cat_short_name {
        (Cat.ShortName)
        <spec_sep>
        <quoted_text_str>
    }

    token cat_long_name {
        (Cat.LongName)
        <spec_sep>
        <quoted_text_str>
    }

    token spec_sep { ':' }

    token quoted_text_str {
        <text_delim>
            (<text_char>*)
        <text_delim>
    }

    token quoted_ne_text_str {
        <text_delim>
            (<text_char>+)
        <text_delim>
    }

    token text_delim { <[']> }

    token text_char { ['\b'|'\q'|<-[\\\']>] }

=head1 EXAMPLES

The following are fragments of actual Concrete Muldis D code.

    MuldisD:':ver<1.2.3>:auth<cpan:DUNCAND>':{ Bool:false }

    Bool:true

    Order:same

    Int:1:11001001

    Int:7:0

    Int:7:644

    Int:9:-34

    Int:9:42

    Int:F:DEADBEEF

    Int:Z:-HELLOWORLD

    UInt:3:301

    PInt:B:A09B

    Rat:1:-1.1

    Rat:9:-1.5

    Rat:9:3.14159

    Rat:A:0.0

    Rat:F:DEADBEEF.FACE

    Rat:Z:0.000AZE

    URat:6:500.001

    PRat:B:A09.B

    Blob:1:00101110100010

    Blob:3:

    Blob:F:A705E

    NEBlob:7:523504376

    Text:'Ceres'

    Text:'サンプル'

    Text:''

    NEText:'Perl'

    Tuple:'sys.Core.Tuple.D0':{}

    Tuple:'glo.the_db.account.user_t':{
        'login_name' => Text:'hartmark',
        'login_pass' => Text:'letmein',
        'is_special' => Bool:true,
    }

    Tuple:'glo.the_db.gene.person_t':{
        'name' => Text:'Michelle',
        'age'  => Int:9:17,
    }

    Database:'sys.Core.Tuple.D0':{}

    Database:'glo.the_db.account':{
        'user' => Relation:'glo.the_db.account.user_r':{ ... },
    }

    Database:'glo.the_db.gene':{
        'person' => Relation:'glo.the_db.gene.person_r':{ ... },
    }

    Relation:'sys.Core.Relation.D0C0':{}

    Relation:'sys.Core.Relation.D0C1':{ {}, }

    Relation:'glo.the_db.account.user_r':{
        {
            'login_name' => Text:'hartmark',
            'login_pass' => Text:'letmein',
            'is_special' => Bool:true,
        },
    }

    Relation:'glo.the_db.gene.person_r':{
        {
            'name' => Text:'Michelle',
            'age'  => Int:9:17,
        },
    }

    Set:'glo.the_db.account.country_name':{
        Text:'Canada',
        Text:'Spain',
        Text:'Jordan',
        Text:'Thailand',
    }

    Set:'glo.the_db.stats.some_ages':{
        Int:9:3,
        Int:9:16,
        Int:9:85,
    }

    Maybe:'glo.the_db.gene.person_death_date':{}

    Maybe:'glo.the_db.gene.person_death_date':{
        Text:'2003.07.24',
    }

    Seq:index:'glo.the_db.gene.sorted_person_name':{
        UInt:9:0 => Text:'Alphonse',
        UInt:9:1 => Text:'Edward',
        UInt:9:2 => Text:'Winry',
    }

    Seq:order:'glo.the_db.stats.samples_by_order':{
        Int:9:57,
        Int:9:45,
        Int:9:63,
        Int:9:61,
    }

    Bag:count:'glo.the_db.inventory.fruit':{
        Text:'Apple'  => PInt:9:500,
        Text:'Orange' => PInt:9:300,
        Text:'Banana' => PInt:9:400,
    }

    Bag:repeat:'glo.the_db.inventory.whatsits':{
        Text:'Foo',
        Text:'Quux',
        Text:'Foo',
        Text:'Bar',
        Text:'Baz',
        Text:'Baz',
    }

=head1 SEE ALSO

Go to L<Language::MuldisD> for the majority of distribution-internal
references, and L<Language::MuldisD::SeeAlso> for the majority of
distribution-external references.

=head1 AUTHOR

Darren Duncan (C<perl@DarrenDuncan.net>)

=head1 LICENSE AND COPYRIGHT

This file is part of the formal specification of the Muldis D language.

Muldis D is Copyright © 2002-2007, Darren Duncan.

See the LICENSE AND COPYRIGHT of L<Language::MuldisD> for details.

=head1 ACKNOWLEDGEMENTS

The ACKNOWLEDGEMENTS in L<Language::MuldisD> apply to this file too.

=cut
