Closed thatrandomperson5 closed 1 year ago
Hard to tell without seeing your grammar, any chance you could post a minimal self contained snippet of nim code + grammar that shows this behavior?
I have no idea where the issue lies so it is hard to make a minimal self contained snippet. I will try tho
Is this good enough?
let testParser = peg("tinput", o: seq[OC]):
name <- >(+Alpha) * ":":
o.add ("name", $1, indent())
value <- >(+Alnum) * !":":
o.add ("value", $1, indent())
tcontent <- (ib.Line(name) * ib.Block(tblock)) | ib.Line(value)
tblock <- +tcontent
tinput <- tblock * !1
It’s minimal but not self contained
I'd like to help you debug this, but [lease try to come up with something I can run to inspect what is happening; I can see from the trace that NPeg is backtracking so your input does not match the grammar, but I can not tell what is wrong with your grammar without having your grammar and the subject string you are trying to parse.
This is self contained but not minimal:
var indentStack = newSeq[int]()
template top[T](s: seq[T]): T =
if s.high == -1:
0
else:
s[s.high]
grammar "ib":
EOL <- "\r\n" | "\n" | "\r" | !1
whitespace <- *Blank
Indent <- >whitespace:
validate len($0) > indentStack.top
indentStack.add len($0)
Dedent <- >whitespace:
let delStack = len($0)
validate delStack < indentStack.top
while delStack < indentStack.top:
discard indentStack.pop
Static <- >whitespace:
validate len($0) == indentStack.top
Line(content) <- ib.Static * content * ib.EOL
Block(content) <- &ib.Indent * content * &ib.Dedent
type OC = tuple[kind: string, s: string, indent: int]
let testParser = peg("tinput", o: seq[OC]):
name <- >(+Alpha) * ":":
o.add ("name", $1, indentStack.len)
value <- >(+Alnum) * !":":
o.add ("value", $1, indentStack.len)
tcontent <- (ib.Line(name) * ib.Block(tblock)) | ib.Line(value)
tblock <- +tcontent
tinput <- tblock * !1
var o = newSeq[OC]()
const testStr = """Foo:
FooBar:
Bar
Bar2
Bar3
Fooo:
Barr
Foooo:
Bar4
Bar5"""
echo testStr
let r = testParser.match(testStr, o)
echo o
doAssert r.ok
@zevv can you run the above successfully?
The parser parses ok, but your Dedent
rule fails because of validate delStack < indentStack.top
, causing the whole shebang to backtrack to the start.
You were right, just needed to change to this: Block(content) <- &ib.Indent * content * (&ib.Dedent | !1)
. Thanks!
I have this line of my parser:
tinput <- tblock * !1
after EOL it should check again for the!1
and end but from the trace below you can see it backs up and starts again then fails. Why is this happening and how can i fix it?