Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | |||
creating:jlists [2025/04/27 21:44] – Finished how to handle infix op ambiguity ahelwer | creating:jlists [2025/04/27 21:57] (current) – Finished first draft ahelwer | ||
---|---|---|---|
Line 188: | Line 188: | ||
Now we write a critical method. | Now we write a critical method. | ||
In '' | In '' | ||
- | < | + | < |
public boolean isNewBullet(Token op) { | public boolean isNewBullet(Token op) { | ||
- | JListInfo current = this.stack.peekFirst(); | + | JListInfo current = stack.peekFirst(); |
return current != null | return current != null | ||
&& current.type == op.type | && current.type == op.type | ||
Line 233: | Line 233: | ||
/\ 1 | /\ 1 | ||
/\ 2 | /\ 2 | ||
- | /\ 3 | ||
</ | </ | ||
The parser will: | The parser will: | ||
Line 246: | Line 245: | ||
If the call to '' | If the call to '' | ||
But we pre-empted it! | But we pre-empted it! | ||
- | So now ''/ | + | So now ''/ |
====== Termination ====== | ====== Termination ====== | ||
Line 258: | Line 257: | ||
/\ 3 | /\ 3 | ||
</ | </ | ||
- | Our code parses this as though it's: | + | Our code parses this as though it' |
<code haskell> | <code haskell> | ||
op == | op == | ||
Line 284: | Line 283: | ||
<code java> | <code java> | ||
public boolean isAboveCurrent(Token tok) { | public boolean isAboveCurrent(Token tok) { | ||
- | JListInfo current = this.stack.peekFirst(); | + | JListInfo current = stack.peekFirst(); |
return current == null || current.column < tok.column; | return current == null || current.column < tok.column; | ||
} | } | ||
Line 321: | Line 320: | ||
Talk of parsing errors nicely segues us onto the topic of error recovery. | Talk of parsing errors nicely segues us onto the topic of error recovery. | ||
+ | Recall that on error, we call '' | ||
+ | Jlists complicate this a bit! | ||
+ | What happens if an error occurs while parsing a jlist and we enter '' | ||
+ | Well, nonsensical things happen. | ||
+ | To fix this we just wipe out our jlist stack at the top of '' | ||
+ | <code java [highlight_lines_extra=" | ||
+ | private void synchronize() { | ||
+ | jlists.dump(); | ||
+ | advance(); | ||
+ | |||
+ | while (!isAtEnd()) { | ||
+ | </ | ||
+ | |||
+ | This calls a new helper we'll define in '' | ||
+ | <code java> | ||
+ | public void dump() { | ||
+ | stack.clear(); | ||
+ | } | ||
+ | </ | ||
+ | Done. | ||
+ | You've successfully parsed vertically-aligned conjunction & disjunction lists in TLA⁺! | ||
+ | This puts you in rarified air. | ||
+ | Only a handful of people in the world possess this knowledge, and now you are among them. | ||
+ | If your code got out of sync during this tutorial, you can find its expected state [[https:// | ||
+ | Continue on the [[creating: | ||
====== Challenges ====== | ====== Challenges ====== | ||
Line 330: | Line 354: | ||
- It's tempting to summarize this chapter as us solving the jlist parsing problem by making jlists have higher precedence than infix operators, but that is not quite the case. Think carefully about what precedence means; is there a difference between what might be called //lexical// precedence - where one interpretation of a token takes higher precedence than another - and parsing precedence? Did we make use of that here? What are some ways that parsers can deal with the problem of the same token having multiple possible meanings? | - It's tempting to summarize this chapter as us solving the jlist parsing problem by making jlists have higher precedence than infix operators, but that is not quite the case. Think carefully about what precedence means; is there a difference between what might be called //lexical// precedence - where one interpretation of a token takes higher precedence than another - and parsing precedence? Did we make use of that here? What are some ways that parsers can deal with the problem of the same token having multiple possible meanings? | ||
- Jlists are not the only context-sensitive language construct in TLA⁺. Nested proof steps are another. Take some time to read the [[https:// | - Jlists are not the only context-sensitive language construct in TLA⁺. Nested proof steps are another. Take some time to read the [[https:// | ||
+ | - Write unit tests for your jlist parsing code. Think of every weird jlist case you can. Look at [[https:// | ||
- If you are familiar with the [[https:// | - If you are familiar with the [[https:// | ||
- Most courses in formal languages skip directly from context-free grammars to Turing machines, but this misses a number of automata of intermediate power. See whether it is possible to use [[https:// | - Most courses in formal languages skip directly from context-free grammars to Turing machines, but this misses a number of automata of intermediate power. See whether it is possible to use [[https:// |