2 ms·
One way I found helpful in giving precise parsing errors without causing excessive false errors is to have the parser auto-completing the missing tokens with pl
by ww520 3y ago
One way I found helpful in giving precise parsing errors without causing excessive false errors is to have the parser auto-completing the missing tokens with placeholder error nodes. E.g.
if (cond1 And ) { ... }
The And operator is missing its right operand, but everything else is valid.
The parser knows the And operator needs two arms. It can complete the missing arm with an error node.
fn parseCondition() {
let leftNode = parseBoolExpr()
if (lookaheadToken() is And)
return parseAnd(leftNode)
if (lookaheadToken() is Or)
...
return leftNode
}
fn parseAnd(leftNode) {
consumeToken()
let rightNode = parseBoolExpr()
if (rightNode != null)
return AndNode(leftNode, rightNode)
else
return AndNode(leftNode, ErrorNode("missing operand", location))
}
In this way, the conditional expression is parsed to completion without interruption. Multiple errors can be handled with completion and recorded. At the end it's a matter of traversing the AST to print out all the ErrorNodes.
- danybittel 3y agoI do have an error node, and it helps but it's still difficult. If I only typed if (cond & It creates error nodes for if and &.. but none of them should show yet. (squiggly lines) if (cond & * Now it should error on the multiply, except if multiply could also be a pointer.
- ww520 3y agoI would say both cases are errors in their current form. When more code is typed in, it can be parsed to validate again.