A problem with calling ambiguous() and ambiguity_metric()

11 views
Skip to first unread message

Ron Savage

unread,
Sep 30, 2014, 10:33:43 PM9/30/14
to marpa-...@googlegroups.com
The docs for Marpa::R2::Scanless:R say, for ambiguous(), "This method should be called after the read() method." I think that should be somehow clarified. Consider this code (BTW the parse is ambiguous):

for
(
my $pos = $self -> recce -> read(\$string);
$pos < $length;
$pos = $self -> recce -> resume($pos)
)
{
# if ($self -> recce -> ambiguity_metric > 1)
# {
# $self -> log(notice => 'Ambiguous parse');
# }

# if ($ambiguous_status = $self -> recce -> ambiguous)
# {
# $self -> log(notice => "Parse is ambiguous: $ambiguous_status");
# }

@event = @{$self -> recce -> events};

#$self -> log(debug => 'Event count: ' . ($#event + 1) . ': ' . join(', ', map{${$_}[0]} @event) . '.');

$event_name     = ${$event[0]}[0];
($start, $span) = $self -> recce -> pause_span;
$lexeme_name    = $self -> recce -> pause_lexeme;
$lexeme         = $self -> recce -> literal($start, $span);

etc down to

}

read() is called, but if I uncomment either of those ifs /inside the loop/ $self -> recce -> value returns undef.

Inside the loop, the first if prints nothing, but affects value().

Inside the loop, the 2nd prints 'No parse' each time thru the loop, and affects value().

Now comment those both out, so the next discussion is only about calls after the loop.

If I have the 1st if after the loop, it says:
Ambiguous parse.

If I have the 2nd if after the loop, it says:
Parse is ambiguous: Ambiguous symch at Glade=9, Symbol=<edge_statement>:
  The ambiguity is from line 1, column 1 to line 1, column 2
  Text is: ->
  There are 2 symches
  Symch 0 is a rule: edge_statement ::= edge_name attribute_definition
  Symch 1 is a rule: edge_statement ::= edge_name
Parse failed. Error: value() called when recognizer is not in tree mode
  The current mode is "forest"
Marpa::R2 exception at lib/MarpaX/Demo/StringParser.pm line 485.

Ruslan Shvedov

unread,
Sep 30, 2014, 10:50:27 PM9/30/14
to marpa-...@googlegroups.com
Perhaps, something like this:

If you need to call value() after ambiguous(), make sure to call series_restart() first.

would make the things clearer.

--
You received this message because you are subscribed to the Google Groups "marpa parser" group.
To unsubscribe from this group and stop receiving emails from it, send an email to marpa-parser...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ron Savage

unread,
Sep 30, 2014, 11:25:34 PM9/30/14
to marpa-...@googlegroups.com
Presumably that means call series_restart() after ambiguous() but before value(), right :-)?

Jeffrey Kegler

unread,
Sep 30, 2014, 11:35:24 PM9/30/14
to marpa-...@googlegroups.com
Before $slr->read() there is no input and therefore no parse, just a recognizer.  So $slr->ambiguous is undefined.

As for the rest, I don't have enough context to see what's going on - I'm not sure anything is wrong.  Could you give as small an example as possible where something is happening that you think should not be happening, describing the desired behavior?

-- jeffrey

Jeffrey Kegler

unread,
Sep 30, 2014, 11:37:53 PM9/30/14
to marpa-...@googlegroups.com
My guess is that $slr->series_restart() is not really related to the original question, but I can't really know from the description so far.


On 09/30/2014 08:25 PM, Ron Savage wrote:
Presumably that means call series_restart() after ambiguous() but before value(), right :-)?

Ruslan Shvedov

unread,
Sep 30, 2014, 11:42:31 PM9/30/14
to marpa-...@googlegroups.com
On Wed, Oct 1, 2014 at 6:25 AM, Ron Savage <r...@savage.net.au> wrote:
Presumably that means call series_restart() after ambiguous() but before value(), right :-)?
:)) Yes.

Ron Savage

unread,
Sep 30, 2014, 11:45:37 PM9/30/14
to marpa-...@googlegroups.com
I'll cut down the big program. I can see how to call the same code twice, with the same input but a different value for a new parameter which exercises the calls in question.

Ruslan Shvedov

unread,
Sep 30, 2014, 11:48:34 PM9/30/14
to marpa-...@googlegroups.com
On Wed, Oct 1, 2014 at 6:37 AM, Jeffrey Kegler <jeffre...@jeffreykegler.com> wrote:
My guess is that $slr->series_restart() is not really related to the original question, but I can't really know from the description so far.
Calling $slr->series_restart() before value() would help prevent this

Parse failed. Error: value() called when recognizer is not in tree mode
  The current mode is "forest"

in the test output.

Jeffrey Kegler

unread,
Sep 30, 2014, 11:52:45 PM9/30/14
to marpa-...@googlegroups.com
Thanks.  If I had to guess, things are behaving as documented and the issue is that the way you're going through the loop is resulting in behavior you don't expect.  But that is just a wild guess and once I see more, I'll know more.

FWIW I have exercised the logic in question a lot, because it's very handy for test cases.  -- jeffrey


On 09/30/2014 08:45 PM, Ron Savage wrote:
I'll cut down the big program. I can see how to call the same code twice, with the same input but a different value for a new parameter which exercises the calls in question.

Ron Savage

unread,
Oct 1, 2014, 1:01:52 AM10/1/14
to marpa-...@googlegroups.com
I've switched over to gists because they allow comments:

https://gist.github.com/ronsavage/a372ca2802f47808374b

As for desired behaviour, you'll note cases 0 & 4 print "Output: !->! OK count: 2." This means the parse is correct, which is true. So why don't all cases do that?

I accept there could be errors after calling value() [that's why I always save the value], but I was expecting the above to be printed in all cases, whether or not the parse is ambiguous.

Jeffrey Kegler

unread,
Oct 1, 2014, 1:17:34 AM10/1/14
to marpa-...@googlegroups.com
OK.  Ambiguity is a property of the parse (grammar + input).  Typically you'll only check for it once the input is complete.  So checking inside the read()/resume() loop is not something you'll typically do, because the interim values will be for the input so far -- not the input at the point where you plan to actually do the parse.  And the ambiguity with the input you plan to parse will usually be what you are interested in.  (All this is assuming you're not up to some very advanced technique.)

Typically you'll

1.) Create the recognizer with new().

2.) Start reading the input with read().

3.) If you're doing event processing, loop, reading more input with resume(), until you're done.

4.) HERE is the point where you'll usually check for ambiguity.  Your input is complete, and you've yet to call value().  The reason you'll probably do it here is that depending on the result,
you may want to handle calling value() differently, or not do it at all.

5.) Call value.

You *can* call ambiguous() at any point after step 2.  But it usually won't make sense until step 4.  After that, you can call it anywhere, and get the same value.  (Because ambiguity is about grammar+input and after step 3 the input is complete.)

Your code looks like it is calling ambiguous() at all sorts of odd locations and, accordingly, getting all sorts of odd answers.

Does this help?  I answered after skimming the code, and if I've missed the intent let me know and I'll look more closely.

-- jeffrey

Ruslan Shvedov

unread,
Oct 1, 2014, 1:23:26 AM10/1/14
to marpa-...@googlegroups.com
I've added a couple of series_restart() calls to your gist, see https://gist.github.com/rns/0371dfcffa6887f4e5a2 to avoid exceptions. The test output makes is arguably more useful that way.

Jeffrey Kegler

unread,
Oct 1, 2014, 1:36:34 AM10/1/14
to marpa-...@googlegroups.com
OK.  Now I understand.  The $slr->ambiguous() method, in producing its diagnosis of the ambiguity, is assuming you'll treat an ambiguity as a fatal error, and won't go on to call value().  At the very least, I should document this. -- jeffrey

Ron Savage

unread,
Oct 1, 2014, 1:56:23 AM10/1/14
to marpa-...@googlegroups.com
Is ambiguity always a fatal error?

I realize the libmarpa does not force that, but are you saying the user should automatically assume that's the case?

Ron Savage

unread,
Oct 1, 2014, 1:56:48 AM10/1/14
to marpa-...@googlegroups.com
Thanx.

Ron Savage

unread,
Oct 1, 2014, 1:58:33 AM10/1/14
to marpa-...@googlegroups.com
On Wednesday, 1 October 2014 15:17:34 UTC+10, Jeffrey Kegler wrote:
OK.  Ambiguity is a property of the parse (grammar + input).  Typically you'll only check for it once the input is complete.  So checking inside the read()/resume() loop is not something you'll typically do, because the interim values will be for the input so far -- not the input at the point where you plan to actually do the parse.  And the ambiguity with the input you plan to parse will usually be what you are interested in.  (All this is assuming you're not up to some very advanced technique.)

Typically you'll

1.) Create the recognizer with new().

2.) Start reading the input with read().

3.) If you're doing event processing, loop, reading more input with resume(), until you're done.

4.) HERE is the point where you'll usually check for ambiguity.  Your input is complete, and you've yet to call value().  The reason you'll probably do it here is that depending on the result,
you may want to handle calling value() differently, or not do it at all.

That makes sense.
 
5.) Call value.

You *can* call ambiguous() at any point after step 2.  But it usually won't make sense until step 4.  After that, you can call it anywhere, and get the same value.  (Because ambiguity is about grammar+input and after step 3 the input is complete.)

Your code looks like it is calling ambiguous() at all sorts of odd locations and, accordingly, getting all sorts of odd answers.

I was experimenting to see what to call when.
 
Does this help?  I answered after skimming the code, and if I've missed the intent let me know and I'll look more closely.

A quick note in the docs re your 5 points would be good.
 

Jeffrey Kegler

unread,
Oct 1, 2014, 6:40:29 AM10/1/14
to marpa-...@googlegroups.com
No, ambiguity is *not* always a fatal error.  I'll have to update the docs to warn the reader that when it is not, and when the ambiguous() method detects ambiguity, the application will need to series_restart() before calling value().

-- jeffrey


On 09/30/2014 10:56 PM, Ron Savage wrote:
Is ambiguity always a fatal error?

I realize the libmarpa does not force that, but are you saying the user should automatically assume that's the case?

Reply all
Reply to author
Forward
0 new messages