-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Syntactic predicates cause nonsensical error messages #194
Comments
Thanks for the report. I plan to look into polishing error messages in 0.9 timeframe. I'll also have a look at this problem at that time. |
In 0.9.0 and current master, the message changed to “Expected undefined but end of input found.”. Minimal grammar reproducing the problem (with empty input): start = &"a" The bug is caused by a combination of two issues:
I’m not sure about the right solution yet. |
I assume that it can be fixed if in |
Yes.
I’m thinking along similar lines — adding a negative reporting flag flipped by the One thing I’m not sure about is how to express negative expectations in the start = "a" / !"b" . / "c" One approach is to embed the value of the negative reporting flag into the expectations: [
{ type: "literal", text: "a", ignoreCase: false, negative: false },
{ type: "literal", text: "b", ignoreCase: false, negative: true },
{ type: "literal", text: "c", ignoreCase: false, negative: false }
] Another approach is to introduce a new expectation type to express negation and use expectation nesting: [
{ type: "literal", text: "a", ignoreCase: false },
{
type: "not",
expectation: { type: "literal", text: "b", ignoreCase: false }
},
{ type: "literal", text: "c", ignoreCase: false }
] The first approach is simpler but it complicates the common case of positive expectations and it would probably lead to more complicated and slower code. The second approach introduces the complexity of nested expectations but keeps the common case as it is now and the code implementing it would likely be smaller and faster. As for the usefulness, negative reporting will make some error messages more accurate. For example, consider this grammar: string = "'" (!"'" .)* "'" With input In any case, if we enable reporting for |
There is a bigger problem with negative reporting than how to express negative expectations in the start = !"a" Now let’s use it on input To implement the desired behavior, we have to do one of two things:
Option 1 is relatively straightforward but will likely result in severe performance degradation (a need to check a flag on every match, successful or not), which makes it unviable in my eyes. Option 2 is somewhat complex to implement, but it won’t result in performance degradation compared to the current state (except when inside the Given the relative complexity of implementation of option 2 and given that I plan to implement other static tracking code as part of performance optimization work going into 1.0.0, I’m moving this issue to 1.0.0 as well. |
The problem is more difficult, than it seems. The fact that the current test set contains the wrong tests hints at it at least and this error still remained unnoticed:
To get such results, it is necessary to remember that predicates do not move a parse position. It means that all expectations received from expression under a predicate shall be executed along with expectations which turn out from further expressions. Below analysis of test cases. Case
It is obvious that they are contradictory -- expression cannot be at the same time to correspond to the end of stream and the Case
Their combining and simplification of expression gives that the end of stream just expected. From this, in particular, follows that grammar start = 'a' / !'b' / 'c' is equivalent to start = 'a' / !'b' EOF / 'c'
EOF = !. and even grammar start = 'a' / EOF / 'c'
EOF = !. however only last 2 parse an input |
…me FAIL to EXPECT. FAILED constant now pushed to the stack by the regular PUSH_FAILED opcode.
…tch result of expression
…me FAIL to EXPECT. FAILED constant now pushed to the stack by the regular PUSH_FAILED opcode. Conflicts: lib/compiler/passes/generate-bytecode.js lib/compiler/passes/generate-js.js test/spec/unit/compiler/passes/generate-bytecode.spec.js
…tch result of expression Conflicts: lib/compiler/passes/generate-bytecode.js test/spec/unit/compiler/passes/generate-bytecode.spec.js
…med` node Conflicts: lib/compiler/passes/generate-bytecode.js test/spec/unit/compiler/passes/generate-bytecode.spec.js
Conflicts: lib/compiler/passes/generate-js.js test/spec/unit/compiler/passes/generate-bytecode.spec.js
Conflicts: test/spec/unit/compiler/passes/generate-bytecode.spec.js
With the following grammar (that matches stuff like "abc", "aabbcc", "aaabbbccc"...), empty test code shows 'Line 1, column 1: Expected end of input but end of input found'. I think it should say 'Expected "a"' instead, as lookahead is looking for 'a'.
The text was updated successfully, but these errors were encountered: