Spirit: how to force backtracking

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

Spirit: how to force backtracking

Boost - Users mailing list

I have the following grammar rule:


value = (int_ % ',') | *ascii::print;


The intention is to parse either a comma-separated list of integers or a string. The rule as such fails in cases like "123ABC", which should be parsed as string.
From the description of the | operator, I would expect the parser to backtrack and try the other alternative when it sees that the first alternative does not match the input. However, I get a parse error instead (this rule is a part of a larger grammar), I guess because the first alternative matches the single integer but the rest of the grammar cannot be matched.

How to rewrite the grammar to resolve this ambiguity, or force spirit to backtrack if the first alternative of 'value' cannot be matched?


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Spirit: how to force backtracking

Boost - Users mailing list
On 11/03/2017 05:20 AM, Stian Zeljko Vrba via Boost-users wrote:

> I have the following grammar rule:
>
>
> value = (int_ % ',') | *ascii::print;
>
> The intention is to parse either a comma-separated list of integers or a string. The rule as such fails in cases like "123ABC", which should be parsed as string.
>  From the description of the | operator, I would expect the parser to backtrack and try the other alternative when it sees that the first alternative does not match the input. However, I get a parse error instead (this rule is a part of a larger grammar), I guess because the first alternative matches the single integer but the rest of the grammar cannot be matched.
>
> How to rewrite the grammar to resolve this ambiguity, or force spirit to backtrack if the first alternative of 'value' cannot be matched?
>
What happens when you reverse the order of the alternatives:


   value = *ascii::print | (int_ % ',');

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Spirit: how to force backtracking

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On Fri, Nov 3, 2017 at 8:20 AM, Stian Zeljko Vrba via Boost-users
<[hidden email]> wrote:

> I have the following grammar rule:
>
>
> value = (int_ % ',') | *ascii::print;
>
> The intention is to parse either a comma-separated list of integers or a
> string. The rule as such fails in cases like "123ABC", which should be
> parsed as string.
> From the description of the | operator, I would expect the parser to
> backtrack and try the other alternative when it sees that the first
> alternative does not match the input. However, I get a parse error instead
> (this rule is a part of a larger grammar), I guess because the first
> alternative matches the single integer but the rest of the grammar cannot be
> matched.
>
> How to rewrite the grammar to resolve this ambiguity, or force spirit to
> backtrack if the first alternative of 'value' cannot be matched?

It seems that "123" is a valid comma-separated list of integers (with 1 integer)
which gets matched. Maybe you could use an eps rule to match a separator
without consuming the input.

> Boost-users mailing list
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users

Regards,
--
Felipe Magno de Almeida
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Spirit: how to force backtracking

Boost - Users mailing list
> It seems that "123" is a valid comma-separated list of integers (with 1 integer)
> which gets matched. Maybe you could use an eps rule to match a separator
> without consuming the input.

Yes, that was the problem, so the first alternative matched and then the rest
of the grammar failed to parse. I managed to fix it with and-predicate like this:

my_int = int_ >> &(lit(',') | lit(':'))

where ',' is expected in the case of list whereas ':' comes from the
higher-level rule which uses my_int rule.

-- Stian

________________________________________
From: Felipe Magno de Almeida <[hidden email]>
Sent: Friday, November 3, 2017 7:32:19 PM
To: [hidden email]
Cc: Stian Zeljko Vrba
Subject: Re: [Boost-users] Spirit: how to force backtracking

On Fri, Nov 3, 2017 at 8:20 AM, Stian Zeljko Vrba via Boost-users
<[hidden email]> wrote:

> I have the following grammar rule:
>
>
> value = (int_ % ',') | *ascii::print;
>
> The intention is to parse either a comma-separated list of integers or a
> string. The rule as such fails in cases like "123ABC", which should be
> parsed as string.
> From the description of the | operator, I would expect the parser to
> backtrack and try the other alternative when it sees that the first
> alternative does not match the input. However, I get a parse error instead
> (this rule is a part of a larger grammar), I guess because the first
> alternative matches the single integer but the rest of the grammar cannot be
> matched.
>
> How to rewrite the grammar to resolve this ambiguity, or force spirit to
> backtrack if the first alternative of 'value' cannot be matched?

It seems that "123" is a valid comma-separated list of integers (with 1 integer)
which gets matched. Maybe you could use an eps rule to match a separator
without consuming the input.

> Boost-users mailing list
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users

Regards,
--
Felipe Magno de Almeida
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users