Parser combinators blog post - #42
Conversation
- Add parser-combinators.html include with interactive parser demos - Add parser-integration.js for handling Dafny-compiled parsers - Add compiled Dafny parsers (ParserSnippets.dfy, SExprParser.dfy, parsers-combined.js) - Add build script for parser combinators - Update Makefile and config for blog post support - Fix bignumber.js path reference to use existing assets/js/bignumber.js
- Start with CharTest (emoji parser) as the foundation
- Introduce Rep with digits parser
- Explain WS as built from CharTest + Rep
- Add IdentifierParser for S-expression building blocks
- Update concatenation examples to build S-expr structure (parsing '(' + identifier)
- Replace choice example with AtomParser (identifier or number)
- Create logical progression that builds toward full S-expression parser
- Simplify IdentifierParser definition to avoid Dafny compilation issues
- Update compiled JavaScript with new parser definitions
- Add comprehensive emoji support for anger: - Add rich joy emoji collection: - Use proper Dafny predicates (IsAngerEmoji, IsJoyEmoji) for better Unicode handling - Update all example buttons with actual emojis instead of placeholder letters - Create engaging, colorful examples that demonstrate parser combinators with fun content - Fix JoyScoreParser to calculate points from actual emoji sequences - Update EmotionParser to handle both anger and joy with proper disjunction - Make parser examples much more visually appealing and memorable
- Update ParseResult to match actual Dafny standard library definition: * ParseSuccess(result: T, remaining: Input) * ParseFailure(level: FailureLevel, data: FailureData) - Add back setInput() function that was removed during autofix - Fix button click behavior to automatically trigger parsing after setting input - Now clicking example buttons immediately shows results without manual Parse click - Accurate representation of Dafny's parser combinator result types
- Add back setInput() function that was removed during autofix
- Fix logic to correctly map input IDs to parse button IDs:
* anger-input anger-parse-button
* joy-input joy-parse-button
* joyscore-input joyscore-parse-button
* etc.
- Use replace('-input', '-parse-button') to find corresponding parse button
- Add error logging if parse button is not found
- Now clicking example buttons will automatically trigger parsing
- Verified pattern is consistent across all parser demo sections
- Replace inline onclick attributes with DOM-based event listeners - Remove setInput() function and all onclick='setInput(...)' attributes - Add DOMContentLoaded event listener that: * Finds all .example-btn elements * Locates their parent .demo-container * Finds input and parse button within same container * Uses button's textContent as input value * Automatically triggers parsing on click Benefits: Much more scalable - no duplication in HTML attributes Cleaner HTML without inline JavaScript Automatic discovery of input/parse button relationships Uses button text content directly as input value More maintainable and easier to add new examples
- Add back the script loading section that was removed during autofix - Load required JavaScript files: * /blog/assets/js/bignumber.js (BigNumber library) * /blog/assets/js/parsers/parsers-combined.js (compiled Dafny parsers) * /blog/assets/js/parsers/parser-integration.js (parser integration layer) - Add browser compatibility shims for require() and process - Parse buttons now work again with the DOM-based button system - Both example buttons and manual parse buttons are functional
- Found and removed duplicate script loading section - Keep only the original script imports that were already present - Parse buttons should now work correctly with single script imports - Lesson learned: Always verify existing content before adding new imports
- Change AngerParser name from 'anger' to 'Angry Smily' for better readability - Add new example button in Joy section: ' Joy then anger!' - This demonstrates how Rep() stops at first non-matching character - Fix build script issues with emoji parsing by using predicate functions - Keep using IsAngerEmoji and IsJoyEmoji predicates for robust Unicode handling
Better css
Restored makefile
|
I'm not sure what to review here. The thousands of lines of JavaScript? Where does the html come from? |
robin-aws
left a comment
There was a problem hiding this comment.
Just reviewed the actual content for this pass, will do another one of all the code.
Very cool and fun post!
…ny-lang/blog into parser-combinators-blog-post
robin-aws
left a comment
There was a problem hiding this comment.
I just skimmed all of the JS code for synchronizing/building the post. It's a ton of logic that looks useful for other blog posts as well, and it's too bad it's not reusable in its current form AFAICT. Definitely want this merged and live, but I'm hoping someone can spend time turning it into something that can be used for other posts or even other interactive Dafny project documentation. If you can think of a way to raise visibility for it I'd appreciate it!
Otherwise just a couple of typos/nits to fix before publishing!
Co-authored-by: Robin Salkeld <salkeldr@amazon.com>
Co-authored-by: Robin Salkeld <salkeldr@amazon.com>
Comment out the exclude section in the config file.
There was a problem hiding this comment.
Deferring to Robin on the JS code. Since you briefly explained why parser combinators can be preferable to parser/lexer generation and how Dafny allows you to generate parsers in a number of languages, I was wondering if you could write a sentence or two somewhere in the introduction or conclusion about the remaining distinguishing factor: what is verified. Is it that the operational execution of a parser (in Dafny) obeys its language-theoretic semantics? That is what I get from skimming ParsersTheorems.dfy. Otherwise, I like the prose as it is.
This PR adds the parser combinators blog post.
The date must be changed when ready for approval.