Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
creating:expressions [2025/04/27 17:30] – Removed infix conjunction & disjunction operators ahelwer | creating:expressions [2025/05/13 15:58] (current) – Fixed lookahead in set literal parsing ahelwer | ||
---|---|---|---|
Line 398: | Line 398: | ||
Now we have to define a table of operators with their details. | Now we have to define a table of operators with their details. | ||
- | For this, create | + | First use the handy Java 17 [[https:// |
+ | Put it at the top of the '' | ||
- | <code java> | + | <code java [highlight_lines_extra=" |
- | package tla; | + | class Parser { |
+ | private static enum Fix { PREFIX, INFIX, POSTFIX } | ||
+ | private static record Operator(Fix fix, TokenType token, | ||
+ | boolean assoc, int lowPrec, int highPrec) {} | ||
- | enum Fix { | + | private |
- | PREFIX, INFIX, POSTFIX | + | |
- | } | + | |
- | + | ||
- | class Operator { | + | |
- | | + | |
- | final TokenType token; | + | |
- | final boolean assoc; | + | |
- | final int lowPrec; | + | |
- | final int highPrec; | + | |
- | + | ||
- | public Operator(Fix fix, TokenType token, boolean assoc, | + | |
- | int lowPrec, int highPrec) { | + | |
- | this.fix = fix; | + | |
- | this.token = token; | + | |
- | this.assoc = assoc; | + | |
- | this.lowPrec = lowPrec; | + | |
- | this.highPrec = highPrec; | + | |
- | } | + | |
- | } | + | |
</ | </ | ||
- | |||
- | For convenience, | ||
- | |||
- | <code java [highlight_lines_extra=" | ||
- | package tla; | ||
- | |||
- | import java.util.List; | ||
- | import java.util.ArrayList; | ||
- | |||
- | import static tla.TokenType.*; | ||
- | import static tla.Fix.*; | ||
- | |||
- | class Parser { | ||
- | </ | ||
- | |||
You can find operator attributes on page 271 of // | You can find operator attributes on page 271 of // | ||
Line 446: | Line 416: | ||
<code java> | <code java> | ||
private static final Operator[] operators = new Operator[] { | private static final Operator[] operators = new Operator[] { | ||
- | new Operator(PREFIX, | + | new Operator(Fix.PREFIX, |
- | new Operator(PREFIX, | + | new Operator(Fix.PREFIX, |
- | new Operator(PREFIX, | + | new Operator(Fix.PREFIX, |
- | new Operator(INFIX, | + | new Operator(Fix.INFIX, |
- | new Operator(INFIX, | + | new Operator(Fix.INFIX, |
- | new Operator(INFIX, | + | new Operator(Fix.INFIX, |
- | new Operator(INFIX, | + | new Operator(Fix.INFIX, |
- | new Operator(INFIX, | + | new Operator(Fix.INFIX, |
- | new Operator(INFIX, | + | new Operator(Fix.INFIX, |
- | new Operator(POSTFIX, | + | new Operator(Fix.POSTFIX, PRIME, |
}; | }; | ||
</ | </ | ||
Line 491: | Line 461: | ||
Expr expr = operatorExpression(prec + 1); | Expr expr = operatorExpression(prec + 1); | ||
- | while ((op = matchOp(INFIX, | + | while ((op = matchOp(Fix.INFIX, prec)) != null) { |
Token operator = previous(); | Token operator = previous(); | ||
Expr right = operatorExpression(op.highPrec + 1); | Expr right = operatorExpression(op.highPrec + 1); | ||
Line 510: | Line 480: | ||
We need to modify the loop to return immediately if the infix operator is not associative: | We need to modify the loop to return immediately if the infix operator is not associative: | ||
<code java [highlight_lines_extra=" | <code java [highlight_lines_extra=" | ||
- | while ((op = matchOp(INFIX, | + | while ((op = matchOp(Fix.INFIX, prec)) != null) { |
Token operator = previous(); | Token operator = previous(); | ||
Expr right = operatorExpression(op.highPrec + 1); | Expr right = operatorExpression(op.highPrec + 1); | ||
Line 528: | Line 498: | ||
Operator op; | Operator op; | ||
- | if ((op = matchOp(PREFIX, | + | if ((op = matchOp(Fix.PREFIX, prec)) != null) { |
Token opToken = previous(); | Token opToken = previous(); | ||
Expr expr = operatorExpression( | Expr expr = operatorExpression( | ||
Line 554: | Line 524: | ||
} | } | ||
- | while ((op = matchOp(POSTFIX, | + | while ((op = matchOp(Fix.POSTFIX, prec)) != null) { |
Token opToken = previous(); | Token opToken = previous(); | ||
expr = new Expr.Unary(opToken, | expr = new Expr.Unary(opToken, | ||
Line 614: | Line 584: | ||
if (match(LEFT_BRACE)) { | if (match(LEFT_BRACE)) { | ||
Token operator = previous(); | Token operator = previous(); | ||
- | List< | + | List< |
- | if (RIGHT_BRACE | + | if (!check(RIGHT_BRACE)) { |
do { | do { | ||
elements.add(expression()); | elements.add(expression()); | ||
Line 666: | Line 636: | ||
Add the '' | Add the '' | ||
- | <code java [highlight_lines_extra=" | + | <code java [highlight_lines_extra=" |
class Parser { | class Parser { | ||
+ | private static enum Fix { PREFIX, INFIX, POSTFIX } | ||
+ | private static record Operator(Fix fix, TokenType token, | ||
+ | boolean assoc, int lowPrec, int highPrec) {} | ||
private static class ParseError extends RuntimeException {} | private static class ParseError extends RuntimeException {} | ||