p_zero_or_more() p_scan() issue

1 view
Skip to first unread message

caio ariede

unread,
Mar 28, 2010, 11:48:48 PM3/28/10
to neoto...@googlegroups.com
Looking for the source code of p_zero_or_more() and p_scan() functions, I noticed that it's not working as expected.

In the following code, I pass a sequence to match only "foobar" or *nothing*, but if the "foo" is present it's not "nothing" (right?):

in root/2:

p_one_or_zero(p_seq([foobar/2]))

... in foobar/2:

p_seq([p_string("foo"), p_string("bar")])

If "bar" is not present, foobar/2 will return a {fail, {expected, ...}} tuple (it's right), but when p_one_or_zero/p_scan detect the failure, the function just ignores the failure and concludes that *there is nothing here*.

I think that the better way for doing this, is to check if only the first item (p_string("foo")) fails, then conclude that *there is nothing of this here*, otherwise return {fail, {expected, ...}}

My thinking is incorrect?

Caio Ariede
http://caioariede.com/

Sean Cribbs

unread,
Mar 29, 2010, 8:45:02 AM3/29/10
to neoto...@googlegroups.com
Caio,

It's hard to tell what that problem is without seeing your grammar.
And I'm assuming you meant "zero_or_more" or "one_or_more", not
"one_or_zero". Also, there shouldn't be a sequence if there's only
one nonterminal in your 'root' rule, it should just be
p_zero_or_more(fun foobar/2)

Is that the bug you're describing?

Sean

> To unsubscribe from this group, send email to
> neotoma-erl+unsubscribegooglegroups.com or reply to this email with the
> words "REMOVE ME" as the subject.
>

caio ariede

unread,
Mar 29, 2010, 9:17:39 AM3/29/10
to neoto...@googlegroups.com
I'm writing in "pure" neotoma code, instead of grammar, because I need to modify the behaviour of some parse funs and not only transform funs.

Grammar #1:

root <- foobar "end";
foobar <- "foo" "bar";

Result:

1> c(foobar).
{ok,foobar}
2> foobar:parse("foobarend").
[["foo","bar"],"end"]
3> foobar:parse("fooend").  
{fail,{expected,{string,"bar"},{{line,1},{column,4}}}}

Grammar #2:

root <- foobar* "end";
foobar <- "foo" "bar";

Result:

1> c(foobar).
{ok,foobar}
2> foobar:parse("foobarend").
[[["foo","bar"]],"end"]
3> foobar:parse("fooend").  
{fail,{expected,{string,"end"},{{line,1},{column,1}}}}

In the second grammar, the {fail, {expected, ...}} must not be the same as the first?

Caio Ariede
http://caioariede.com/

caio ariede

unread,
Mar 29, 2010, 11:52:12 AM3/29/10
to neoto...@googlegroups.com
And yes, I meant p_zero_or_more, just typo sorry.

Caio Ariede
http://caioariede.com/

Sean Cribbs

unread,
Mar 29, 2010, 3:38:38 PM3/29/10
to neoto...@googlegroups.com
That's the expected behavior. Since the entire "foobar" nonterminal
didn't match, it leaves "foo" in buffer, and then tries to match
"end". Remember, zero_or_more (*) is equivalent to optional
repetition (+?).

caio ariede

unread,
Mar 29, 2010, 4:19:34 PM3/29/10
to neoto...@googlegroups.com
And the column *1* in:


3> foobar:parse("fooend").  
{fail,{expected,{string,"end"},{{line,1},{column,1}}}}

It's correct?

Caio Ariede
http://caioariede.com/

Sean Cribbs

unread,
Mar 29, 2010, 5:43:06 PM3/29/10
to neoto...@googlegroups.com
Yes, because it didn't advance the index - it is still trying to match
at the first position. Although "foo" matched further down the parse
tree, the entire parent rule didn't match, so the result was a
failure.

Sean

Reply all
Reply to author
Forward
0 new messages