x3 grammar rules

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

x3 grammar rules

Lane
I'm trying to parse a mapped file using spirit x3. Eventually, I'd
like to parse these lines so that they populate structures, but one
step at a time.

Basically, I'd like to know if I'm going about the grammar correctly
as I'm trying to parse the entire file at once.

    namespace client {
        // ...

        // parse line of characters
        x3::rule<class _desc> const _desc = "_desc";
        auto const _desc_def = *(char_ - eol);
        BOOST_SPIRIT_DEFINE(_desc);

        // parse 1 2 3
        x3::rule<class _number> const _number = "_number";
        auto const _number_def = int_ >> int_ >> int_;
        BOOST_SPIRIT_DEFINE(_number);

        // parse 1 0.0 0.0 0.0
        x3::rule<class _point> const _point = "_point";
        auto const _point_def = int_ >> double_ >> double_ >> double_;
        BOOST_SPIRIT_DEFINE(_point);

        // parse int chars int int int "1 tri 1 2 3"
        x3::rule<class _element> const _element = "_element";
        auto const _element_def = int_ >> *(char_) >> int_ >> int_ >> int_;
        BOOST_SPIRIT_DEFINE(_element);

        // parse int int int "4 5 6"
        x3::rule<class _elem_points> const _elem_points = "_elem_points";
        auto const _elem_points_def = int_ >> int_ >> int_;
        BOOST_SPIRIT_DEFINE(_elem_points);

        x3::rule<class _group> const _group = "_group";
        auto const _group_def = int_ >> *(char_);
        BOOST_SPIRIT_DEFINE(_group);

        auto description = skip(blank) [
            *(_desc >> eol)
        ];

        auto numbers = skip(blank) [
            *(_number >> eol)
        ];

        auto point = skip(blank) [
            *(_point >> eol)
        ];

        // parse two lines instead of 2nd line which looks the same, but
        // has no element before it
        // 1 tri  1 2 3
        // 4 5 6
        auto element = skip(blank) [
            *(_element >> eol >> _elem_points >> eol)
        ];

        auto group = skip(blank) [
            *(_group >> eol)
        ];

        auto pr = [&] (auto& ctx) {
            std::cout << "hi " << std::endl;
            //cout << "desc = " << _attr(ctx) << endl;
        };

        auto const input = description[pr]
            >> numbers[pr]
            >> point[pr]
            >> element[pr]
            >> group[pr];
        }
    }

    int main() {
        // ...

        mapped_file_source map(fil);
        istringstream iss(map.data());
        map.close();

        boost::spirit::istream_iterator iter(iss >> noskipws), eof;

        x3::parse(iter, eof,  client::input);

        return (iter != eof);
    }

And the file I'm trying to parse is formatted as follows, only much larger.

    my file description
    1 2 3
    1 0.0 0.0 0.0
    2 0.0 0.0 0.0
    3 0.0 0.0 0.0
    1 tri 1 3 1
    1 2 3
    2 tri 1 3 1
    4 5 6
    3 tri 1 3 1
    7 8 9
    1 end

Here is the output of running this. I get a 'hi' for each rule, but I
don't get an error saying it didn't parse the entire file. Can anyone
offer some guidance.
---
hi
hi
hi
hi
hi

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: x3 grammar rules

Olaf Peter
[...]

> Basically, I'd like to know if I'm going about the grammar correctly
> as I'm trying to parse the entire file at once.
>
>      namespace client {
>          // ...
>
>          // parse line of characters
>          x3::rule<class _desc> const _desc = "_desc";
>          auto const _desc_def = *(char_ - eol);
>          BOOST_SPIRIT_DEFINE(_desc);
>
>          // parse 1 2 3
>          x3::rule<class _number> const _number = "_number";
>          auto const _number_def = int_ >> int_ >> int_;
>          BOOST_SPIRIT_DEFINE(_number);
>
>          // parse 1 0.0 0.0 0.0
>          x3::rule<class _point> const _point = "_point";
>          auto const _point_def = int_ >> double_ >> double_ >> double_;
>          BOOST_SPIRIT_DEFINE(_point);
>
>          // parse int chars int int int "1 tri 1 2 3"
>          x3::rule<class _element> const _element = "_element";
>          auto const _element_def = int_ >> *(char_) >> int_ >> int_ >> int_;
>          BOOST_SPIRIT_DEFINE(_element);
>
>          // parse int int int "4 5 6"
>          x3::rule<class _elem_points> const _elem_points = "_elem_points";
>          auto const _elem_points_def = int_ >> int_ >> int_;
>          BOOST_SPIRIT_DEFINE(_elem_points);
>
>          x3::rule<class _group> const _group = "_group";
>          auto const _group_def = int_ >> *(char_);
>          BOOST_SPIRIT_DEFINE(_group);
>
>          auto description = skip(blank) [
>              *(_desc >> eol)
>          ];
>
>          auto numbers = skip(blank) [
>              *(_number >> eol)
>          ];
>
>          auto point = skip(blank) [
>              *(_point >> eol)
>          ];
>
>          // parse two lines instead of 2nd line which looks the same, but
>          // has no element before it
>          // 1 tri  1 2 3
>          // 4 5 6
>          auto element = skip(blank) [
>              *(_element >> eol >> _elem_points >> eol)
>          ];
>
>          auto group = skip(blank) [
>              *(_group >> eol)
>          ];
>
>          auto pr = [&] (auto& ctx) {
>              std::cout << "hi " << std::endl;
>              //cout << "desc = " << _attr(ctx) << endl;
>          };
>
>          auto const input = description[pr]
>              >> numbers[pr]
>              >> point[pr]
>              >> element[pr]
>              >> group[pr];
>          }
>      }
>
>      int main() {
>          // ...
>
>          mapped_file_source map(fil);
>          istringstream iss(map.data());
>          map.close();
>
>          boost::spirit::istream_iterator iter(iss >> noskipws), eof;
>
>          x3::parse(iter, eof,  client::input);
>
>          return (iter != eof);
>      }
>
> And the file I'm trying to parse is formatted as follows, only much larger.
>
>      my file description
>      1 2 3
>      1 0.0 0.0 0.0
>      2 0.0 0.0 0.0
>      3 0.0 0.0 0.0
>      1 tri 1 3 1
>      1 2 3
>      2 tri 1 3 1
>      4 5 6
>      3 tri 1 3 1
>      7 8 9
>      1 end
>
> Here is the output of running this. I get a 'hi' for each rule, but I
> don't get an error saying it didn't parse the entire file. Can anyone
> offer some guidance.

at the end of input file, is 'end' at the last line a keyword and your
marker for EOL since I've not seen a rule for the keyword 'end'. This
would explain the remainding iter != eof

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: x3 grammar rules

Lane
It's just text. I've changed the last line from '1 end' to be ...
        1 my_label

The rule to cover this is listed as ...

    x3::rule<class _group> const _group = "_group";
    auto const _group_def = int_ >> *(char_);
    BOOST_SPIRIT_DEFINE(_group);

On Thu, Jul 6, 2017 at 12:31 AM, Olaf Peter <[hidden email]> wrote:

> [...]
>
>> Basically, I'd like to know if I'm going about the grammar correctly
>> as I'm trying to parse the entire file at once.
>>
>>      namespace client {
>>          // ...
>>
>>          // parse line of characters
>>          x3::rule<class _desc> const _desc = "_desc";
>>          auto const _desc_def = *(char_ - eol);
>>          BOOST_SPIRIT_DEFINE(_desc);
>>
>>          // parse 1 2 3
>>          x3::rule<class _number> const _number = "_number";
>>          auto const _number_def = int_ >> int_ >> int_;
>>          BOOST_SPIRIT_DEFINE(_number);
>>
>>          // parse 1 0.0 0.0 0.0
>>          x3::rule<class _point> const _point = "_point";
>>          auto const _point_def = int_ >> double_ >> double_ >> double_;
>>          BOOST_SPIRIT_DEFINE(_point);
>>
>>          // parse int chars int int int "1 tri 1 2 3"
>>          x3::rule<class _element> const _element = "_element";
>>          auto const _element_def = int_ >> *(char_) >> int_ >> int_ >>
>> int_;
>>          BOOST_SPIRIT_DEFINE(_element);
>>
>>          // parse int int int "4 5 6"
>>          x3::rule<class _elem_points> const _elem_points = "_elem_points";
>>          auto const _elem_points_def = int_ >> int_ >> int_;
>>          BOOST_SPIRIT_DEFINE(_elem_points);
>>
>>          x3::rule<class _group> const _group = "_group";
>>          auto const _group_def = int_ >> *(char_);
>>          BOOST_SPIRIT_DEFINE(_group);
>>
>>          auto description = skip(blank) [
>>              *(_desc >> eol)
>>          ];
>>
>>          auto numbers = skip(blank) [
>>              *(_number >> eol)
>>          ];
>>
>>          auto point = skip(blank) [
>>              *(_point >> eol)
>>          ];
>>
>>          // parse two lines instead of 2nd line which looks the same, but
>>          // has no element before it
>>          // 1 tri  1 2 3
>>          // 4 5 6
>>          auto element = skip(blank) [
>>              *(_element >> eol >> _elem_points >> eol)
>>          ];
>>
>>          auto group = skip(blank) [
>>              *(_group >> eol)
>>          ];
>>
>>          auto pr = [&] (auto& ctx) {
>>              std::cout << "hi " << std::endl;
>>              //cout << "desc = " << _attr(ctx) << endl;
>>          };
>>
>>          auto const input = description[pr]
>>              >> numbers[pr]
>>              >> point[pr]
>>              >> element[pr]
>>              >> group[pr];
>>          }
>>      }
>>
>>      int main() {
>>          // ...
>>
>>          mapped_file_source map(fil);
>>          istringstream iss(map.data());
>>          map.close();
>>
>>          boost::spirit::istream_iterator iter(iss >> noskipws), eof;
>>
>>          x3::parse(iter, eof,  client::input);
>>
>>          return (iter != eof);
>>      }
>>
>> And the file I'm trying to parse is formatted as follows, only much
>> larger.
>>
>>      my file description
>>      1 2 3
>>      1 0.0 0.0 0.0
>>      2 0.0 0.0 0.0
>>      3 0.0 0.0 0.0
>>      1 tri 1 3 1
>>      1 2 3
>>      2 tri 1 3 1
>>      4 5 6
>>      3 tri 1 3 1
>>      7 8 9
>>      1 end
>>
>> Here is the output of running this. I get a 'hi' for each rule, but I
>> don't get an error saying it didn't parse the entire file. Can anyone
>> offer some guidance.
>
>
> at the end of input file, is 'end' at the last line a keyword and your
> marker for EOL since I've not seen a rule for the keyword 'end'. This would
> explain the remainding iter != eof
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: x3 grammar rules

Lane
Just to clarify ... I don't get any incomplete parsing errors, so
maybe it's working and I need to start trying to capture the parsed
data. I've have the line ...

    cout << _attr(ctx) << endl;

... within the pr lambda and thought I should be seeing parsed data to
help debug and understand what's going on.

Mainly I'd just like for someone to give comments about doing it like
this as it is my first spirit parser and confirm that this should
work.

On Thu, Jul 6, 2017 at 8:55 PM, Lane
<[hidden email]> wrote:

> It's just text. I've changed the last line from '1 end' to be ...
>         1 my_label
>
> The rule to cover this is listed as ...
>
>     x3::rule<class _group> const _group = "_group";
>     auto const _group_def = int_ >> *(char_);
>     BOOST_SPIRIT_DEFINE(_group);
>
> On Thu, Jul 6, 2017 at 12:31 AM, Olaf Peter <[hidden email]> wrote:
>> [...]
>>
>>> Basically, I'd like to know if I'm going about the grammar correctly
>>> as I'm trying to parse the entire file at once.
>>>
>>>      namespace client {
>>>          // ...
>>>
>>>          // parse line of characters
>>>          x3::rule<class _desc> const _desc = "_desc";
>>>          auto const _desc_def = *(char_ - eol);
>>>          BOOST_SPIRIT_DEFINE(_desc);
>>>
>>>          // parse 1 2 3
>>>          x3::rule<class _number> const _number = "_number";
>>>          auto const _number_def = int_ >> int_ >> int_;
>>>          BOOST_SPIRIT_DEFINE(_number);
>>>
>>>          // parse 1 0.0 0.0 0.0
>>>          x3::rule<class _point> const _point = "_point";
>>>          auto const _point_def = int_ >> double_ >> double_ >> double_;
>>>          BOOST_SPIRIT_DEFINE(_point);
>>>
>>>          // parse int chars int int int "1 tri 1 2 3"
>>>          x3::rule<class _element> const _element = "_element";
>>>          auto const _element_def = int_ >> *(char_) >> int_ >> int_ >>
>>> int_;
>>>          BOOST_SPIRIT_DEFINE(_element);
>>>
>>>          // parse int int int "4 5 6"
>>>          x3::rule<class _elem_points> const _elem_points = "_elem_points";
>>>          auto const _elem_points_def = int_ >> int_ >> int_;
>>>          BOOST_SPIRIT_DEFINE(_elem_points);
>>>
>>>          x3::rule<class _group> const _group = "_group";
>>>          auto const _group_def = int_ >> *(char_);
>>>          BOOST_SPIRIT_DEFINE(_group);
>>>
>>>          auto description = skip(blank) [
>>>              *(_desc >> eol)
>>>          ];
>>>
>>>          auto numbers = skip(blank) [
>>>              *(_number >> eol)
>>>          ];
>>>
>>>          auto point = skip(blank) [
>>>              *(_point >> eol)
>>>          ];
>>>
>>>          // parse two lines instead of 2nd line which looks the same, but
>>>          // has no element before it
>>>          // 1 tri  1 2 3
>>>          // 4 5 6
>>>          auto element = skip(blank) [
>>>              *(_element >> eol >> _elem_points >> eol)
>>>          ];
>>>
>>>          auto group = skip(blank) [
>>>              *(_group >> eol)
>>>          ];
>>>
>>>          auto pr = [&] (auto& ctx) {
>>>              std::cout << "hi " << std::endl;
>>>              //cout << "desc = " << _attr(ctx) << endl;
>>>          };
>>>
>>>          auto const input = description[pr]
>>>              >> numbers[pr]
>>>              >> point[pr]
>>>              >> element[pr]
>>>              >> group[pr];
>>>          }
>>>      }
>>>
>>>      int main() {
>>>          // ...
>>>
>>>          mapped_file_source map(fil);
>>>          istringstream iss(map.data());
>>>          map.close();
>>>
>>>          boost::spirit::istream_iterator iter(iss >> noskipws), eof;
>>>
>>>          x3::parse(iter, eof,  client::input);
>>>
>>>          return (iter != eof);
>>>      }
>>>
>>> And the file I'm trying to parse is formatted as follows, only much
>>> larger.
>>>
>>>      my file description
>>>      1 2 3
>>>      1 0.0 0.0 0.0
>>>      2 0.0 0.0 0.0
>>>      3 0.0 0.0 0.0
>>>      1 tri 1 3 1
>>>      1 2 3
>>>      2 tri 1 3 1
>>>      4 5 6
>>>      3 tri 1 3 1
>>>      7 8 9
>>>      1 end
>>>
>>> Here is the output of running this. I get a 'hi' for each rule, but I
>>> don't get an error saying it didn't parse the entire file. Can anyone
>>> offer some guidance.
>>
>>
>> at the end of input file, is 'end' at the last line a keyword and your
>> marker for EOL since I've not seen a rule for the keyword 'end'. This would
>> explain the remainding iter != eof
>>
>> ------------------------------------------------------------------------------
>> Check out the vibrant tech community on one of the world's most
>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>> _______________________________________________
>> Spirit-general mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/spirit-general

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general