Thread: [Pyparsing] Salvaging a failed parse
Brought to you by:
ptmcg
From: Gre7g L. <haf...@ya...> - 2008-03-18 23:00:43
|
First off, let me just say that the compiler I wrote with PyParsing is actually functional and is working amazingly well. It has left me absolutely speechless. I can't even begin to imagine how much work it would have taken to get to this point without an incredible tool like this. Secondly, I apologize for my earlier post asking about something that I should have seen in the FAQs. I didn't even notice that there was an FAQ section on the website! Doh. Finally, on to the question at hand... How can I best recover from a failed parse? I realize that's a really open-ended question, so let me take a moment to explain what's happening, how my gut says I should handle this, and then I hopefully I can get some feedback on whether this is the best way to go about it or not. My compiler is really good at detecting logic errors, like trying to assign a value to a constant, but if the user's error causes the parse to fail, then I don't have much useful feedback I can give them. For example, here's a chunk of invalid code: a=5; for (i = 5; i < 10; i = 7) { c=9; if (a < 6) a = 7 else b = 9; } x = 5; Note that "a = 7" is missing a ";". The parser will decide that the assignment doesn't match the pattern I specified, so therefor the "if" statement doesn't match the pattern I specified, so therefore the "for" statement doesn't match the pattern I specified. The parser is 100% correct, but if I tell the user "Expected end of text (at char 6), (line:3, col:1)" then I'm not being helpful. The problem is farther down and if I tell them the problem is on the for statement, they will never find it. Here's a short example program illustrating this: http://pastie.textmate.org/167541 My gut says that the way to "fix" this is to look at the position argument passed to my setParseAction instances and keep track of the farthest position through the file that the parser managed to get. The logic here being that farthest parse position was *PROBABLY* the closest to being successful. I won't really have a good idea of why the parse failed, if it does, but at least I'll have a position in the file, and that's a good start. Here's some more example code, illustrating the process: http://pastie.textmate.org/167542 Is this how you'd handle this? Is there a better way? Is there a pitfall I'm ignoring? Also, since this will only give me a linear position into the file, does PyParsing expose a method to convert this to a line/column like the ParseException does, or should I just count up the CR's and do the math myself? Many thanks again, Gre7g __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com |
From: Paul M. <pt...@au...> - 2008-03-25 05:19:41
|
Greg - >>> Does PyParsing expose a method to convert this to a line/column like the ParseException does, or should I just count up the CR's and do the math myself? >>> Yes, pyparsing has lineno(loc,string) and col(loc,string) methods for converting an absolute loc into line number and column number. You can see them in use in the body of this FAQ: http://pyparsing-public.wikispaces.com/FAQs#toc2. The line(loc,string) function will give you the line of text corresponding to the loc value. (Beware when using col() if there are tabs in your input text. Pyparsing expands tabs to 8-space tabstops by default so column numbers may end up different than you expect. Use parseWithTabs to change this default behavior. The html docs that come with pyparsing have more details on this issue.) There are also usage examples in http://pyparsing.wikispaces.com/space/showimage/linenoExample.py. Sorry to not respond sooner, I was out of the country on vacation, and just getting my head back together. -- Paul |