Note that there are some explanatory texts on larger screens.

plurals
  1. POImproving error messages with pyparsing
    primarykey
    data
    text
    <p><strong>Edit:</strong> I did a first version, which Eike helped me to advance quite a bit on it. I'm now stuck to a more specific problem, which I will describe bellow. You can have a look at the original question in the <a href="https://stackoverflow.com/posts/15897602/revisions">history</a></p> <hr> <p>I'm using pyparsing to parse a small language used to request specific data from a database. It features numerous keyword, operators and datatypes as well as boolean logic.</p> <p>I'm trying to improve the error message sent to the user when he does a syntax error, since the current one is not very useful. I designed a small example, similar to what I'm doing with the language aforementioned but much smaller:</p> <pre><code>#!/usr/bin/env python from pyparsing import * def validate_number(s, loc, tokens): if int(tokens[0]) != 0: raise ParseFatalException(s, loc, "number musth be 0") def fail(s, loc, tokens): raise ParseFatalException(s, loc, "Unknown token %s" % tokens[0]) def fail_value(s, loc, expr, err): raise ParseFatalException(s, loc, "Wrong value") number = Word(nums).setParseAction(validate_number).setFailAction(fail_value) operator = Literal("=") error = Word(alphas).setParseAction(fail) rules = MatchFirst([ Literal('x') + operator + number, ]) rules = operatorPrecedence(rules | error , [ (Literal("and"), 2, opAssoc.RIGHT), ]) def try_parse(expression): try: rules.parseString(expression, parseAll=True) except Exception as e: msg = str(e) print("%s: %s" % (msg, expression)) print(" " * (len("%s: " % msg) + (e.loc)) + "^^^") </code></pre> <p>So basically, the only things which we can do with this language, is writing series of <code>x = 0</code>, joined together with <code>and</code> and parenthesis.</p> <p>Now, there are cases, when <code>and</code> and parenthesis are used, where the error reporting is not very good. Consider the following examples:</p> <pre><code>&gt;&gt;&gt; try_parse("x = a and x = 0") # This one is actually good! Wrong value (at char 4), (line:1, col:5): x = a and x = 0 ^^^ &gt;&gt;&gt; try_parse("x = 0 and x = a") Expected end of text (at char 6), (line:1, col:1): x = 0 and x = a ^^^ &gt;&gt;&gt; try_parse("x = 0 and (x = 0 and (x = 0 and (x = a)))") Expected end of text (at char 6), (line:1, col:1): x = 0 and (x = 0 and (x = 0 and (x = a))) ^^^ &gt;&gt;&gt; try_parse("x = 0 and (x = 0 and (x = 0 and (x = 0)))") Expected end of text (at char 6), (line:1, col:1): x = 0 and (x = 0 and (x = 0 and (xxxxxxxx = 0))) ^^^ </code></pre> <p>Actually, it seems that if the parser can't <strong>parse</strong> (and <em>parse</em> here is important) something after a <code>and</code>, it doesn't produce good error messages anymore :(</p> <p>And I mean <strong>parse</strong>, since if it can parse 5 but the "validation" fails in the parse action, it still produces a good error message. But, if it can't parse a valid number (like <code>a</code>) or a valid keyword (like <code>xxxxxx</code>), it stops producing the right error messages.</p> <p>Any idea?</p>
    singulars
    1. This table or related slice is empty.
    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.
 

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