|
Lime Parser Generator 0.1.0
Runtime-extensible LALR(1) parser with SIMD tokenization and LLVM JIT
|
This guide covers converting a Yacc grammar (.y) to Lime format (.lime). Yacc and Bison share most syntax, so this guide focuses on Yacc-specific considerations. For the full directive mapping and syntax translation rules, see MIGRATION_FROM_BISON.md – nearly everything there applies to Yacc as well.
Yacc generates a pull parser that calls yylex() internally. Lime generates a push parser where you feed tokens one at a time:
Yacc:
Lime:
Yacc parsers use global variables (yylval, yychar, yydebug, etc.) by default. Lime parsers are always reentrant – the parser state is an opaque pointer returned by ParseAlloc(). Multiple Lime parsers can run concurrently with no shared state.
Yacc tightly couples the parser to a yylex() function (typically generated by Lex/Flex). Lime has no built-in lexer integration. Write a hand-coded tokenizer or adapt your Lex output to feed tokens via Parse().
| Yacc | Lime | Notes |
|---|---|---|
%{ ... %} (prologue) | include { ... } | Code inserted at file top |
token TOK | token TOK. | Period required |
left TOK | left TOK. | Period required |
right TOK | right TOK. | Period required |
nonassoc TOK | nonassoc TOK. | Period required |
type <tag> sym | type sym {CType} | Direct C type, no union tag |
union { ... } | token_type {T} + per-symbol type | No shared union |
start sym | start_symbol sym | Different keyword |
prec TOK | [TOK] | Square brackets after rule RHS |
$$ | A | LHS semantic value |
$1, $2, ... | B, C, ... | RHS semantic values |
yyerror(msg) | syntax_error { ... } | Inline callback block |
Yacc:
Lime:
Note: Yacc allows single-character literals (‘’+'); Lime requires named tokens (PLUS`). You must define named tokens for all punctuation and map them in your tokenizer.
Most Yacc grammars use union to define the semantic value type:
Lime approach: define a struct or union as your token_type, and use per-symbol type for non-terminals:
Alternatively, if all tokens share a single type, use that directly:
$<tag>N casts: Yacc allows $<ival>3 to cast a semantic value through a union member. Lime does not support this. Use explicit casts in your action code if needed.@N position tracking: Yacc's @1, @2 location tracking is not built into Lime. Pass position information through your token type or extra argument.YYACCEPT / YYABORT: Yacc macros for early accept or abort have no direct equivalent. Lime parsers terminate naturally when they receive token 0 (end of input) or enter an unrecoverable error state.YYERROR: The Yacc macro to trigger error recovery from within an action is not available. Use your extra_argument to set an error flag and check it after parsing completes.expect: Yacc allows expect N to suppress conflict warnings. Lime reports all conflicts. Resolve them with precedence rules or grammar restructuring..y to .lime%{ ... %} prologue with include { ... }union with token_type and per-symbol typestart with start_symboltoken, left, right, nonassoc lines: to ::=, | to separate rules, ; to .$$ with A, $1 with B, $2 with C, etc.prec TOKEN with [TOKEN]) with named tokens (PLUS)Replaceyyerror()withsyntax_error { ... }blockRewrite the main loop fromyyparse()toParse()` push model