Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Pyparsing will always have somewhat bad error messages, because it backtracks. The error message is generated in the last rule that the parser tries. The parser can't know where the error really is, it only knows that there is no matching rule. </p> <p>For good error messages you need a parser that gives up early. These parsers are less flexible than Pyparsing, but most conventional programming languages can be parsed with such parsers. (C++ and Scala IMHO can't.) </p> <p>To improve error messages in Pyparsing use the <code>-</code> operator, it works like the <code>+</code> operator, but it does not backtrack. You would use it like this:</p> <pre><code>assignment = Literal("let") - varname - "=" - expression </code></pre> <p>Here is a <a href="https://web.archive.org/web/20160821175151/http://pyparsing.wikispaces.com/share/view/30875955" rel="nofollow noreferrer">small article on improving error reporting</a>, by Pyparsing's author.</p> <p><strong>Edit</strong></p> <p>You could also generate good error messages for the invalid numbers in the parse actions that do the validation. If the number is invalid you raise an exception that is not caught by Pyparsing. This exception can contain a good error message.</p> <p>Parse actions can have three arguments [1]:</p> <ul> <li>s = the original string being parsed (see note below)</li> <li>loc = the location of the matching substring</li> <li>toks = a list of the matched tokens, packaged as a <code>ParseResults</code> object</li> </ul> <p>There are also three useful helper methods for creating good error messages [2]:</p> <ul> <li><code>lineno(loc, string)</code> - function to give the line number of the location within the string; the first line is line 1, newlines start new rows.</li> <li><code>col(loc, string)</code> - function to give the column number of the location within the string; the first column is column 1, newlines reset the column number to 1.</li> <li><code>line(loc, string)</code> - function to retrieve the line of text representing <code>lineno(loc, string)</code>. Useful when printing out diagnostic messages for exceptions.</li> </ul> <p>Your validating parse action would then be like this:</p> <pre><code>def validate_odd_number(s, loc, toks): value = toks[0] value = int(value) if value % 2 == 0: raise MyFatalParseException( "not an odd number. Line {l}, column {c}.".format(l=lineno(loc, s), c=col(loc, s))) </code></pre> <p>[1] <a href="http://pythonhosted.org/pyparsing/pyparsing.pyparsing.ParserElement-class.html#setParseAction" rel="nofollow noreferrer">http://pythonhosted.org/pyparsing/pyparsing.pyparsing.ParserElement-class.html#setParseAction</a></p> <p>[2] <a href="https://web.archive.org/web/20170911072516/http://pyparsing.wikispaces.com:80/HowToUsePyparsing" rel="nofollow noreferrer">HowToUsePyparsing</a></p> <p><strong>Edit</strong></p> <p>Here [3] is an improved version of the question's current (2013-4-10) script. It gets the example errors right, but other error are indicated at the wrong position. I believe there are bugs in my version of Pyparsing ('1.5.7'), but maybe I just don't understand how Pyparsing works. The issues are:</p> <ul> <li>ParseFatalException seems not to be always fatal. The script works as expected when I use my own exception.</li> <li>The <code>-</code> operator seems not to work.</li> </ul> <p>[3] <a href="http://pastebin.com/7E4kSnkm" rel="nofollow noreferrer">http://pastebin.com/7E4kSnkm</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload