Skip to content

Add formal EBNF grammar specification for Maya date parser - #29

Draft
drewsonne with Copilot wants to merge 4 commits into
mainfrom
copilot/create-grammar-specification
Draft

Add formal EBNF grammar specification for Maya date parser#29
drewsonne with Copilot wants to merge 4 commits into
mainfrom
copilot/create-grammar-specification

Conversation

Copilot AI commented Jan 5, 2026

Copy link
Copy Markdown

The parser has no formal grammar specification. Parsing logic is embedded across 4 layers of state machine code, making it difficult to understand the complete language, identify edge cases, or verify completeness.

Changes

Grammar Documentation (docs/GRAMMAR.md)

Lexical Tokens

  • 9 terminal types: NUMBER, WORD, WILDCARD, PERIOD, PLUS, MINUS, HASH, NEWLINE, SPACE
  • Character-level definitions following ISO/IEC 14977:1996 EBNF

Syntactic Grammar

expression     ::= operation | fullDate | calendarRound | longCount
calendarRound  ::= tzolkin WS+ haab
longCount      ::= lcPart {PERIOD lcPart}
operation      ::= expression WS+ operator WS+ expression

Semantic Constraints

  • Tzolkin: coefficients 1-13, 20 valid day names
  • Haab: coefficients 0-19 (0-4 for Wayeb), 19 valid month names
  • Long Count: base-18 for Winal (position 3), base-20 elsewhere

Ambiguities Resolved

  1. Partial Calendar Rounds not allowed at top level
  2. Whitespace optional between number/word, required between components
  3. Comments only inline (after expression) or standalone (cannot split expressions)
  4. Consecutive wildcards (**) tokenize as two separate WILDCARD tokens
  5. Empty input and blank lines are valid

Examples

  • 50+ examples covering all productions
  • Valid/invalid cases with explanations
  • Edge cases: 6Manik' 5Mol (no space after number), 8.7.6.5.4.17.2.1 (8-part Long Count)

Diagrams

  • 7 ASCII railroad diagrams for visual reference

Coverage

Grammar verified against 85 existing parser tests (100% coverage across layers 0-3).

Original prompt

This section details on the original issue you should resolve

<issue_title>Create Formal Grammar Specification</issue_title>
<issue_description>
Parent: Epic: Stabilize Parser & Upgrade to maya-dates >= 1.3.0
Priority: High
Complexity: Medium
Estimated Effort: 16 hours
Labels: documentation, grammar, specification

Description

Document the Maya date parsing grammar in EBNF notation. This serves as the specification for the new parser implementation and helps identify edge cases/ambiguities in the current informal parsing logic.

Problem Statement

The current parser has no formal grammar specification. Parsing logic is embedded across 4 layers of state machine code, making it:

  • Hard to understand the complete language
  • Difficult to identify edge cases
  • Impossible to verify completeness
  • Challenging to discuss design decisions

Grammar Coverage

The grammar must document:

  1. Calendar Round: tzolkin haab (e.g., 4 Ajaw 8 Kumk'u)
  2. Long Count: baktun.katun.tun.winal.kin (e.g., 9.16.19.17.19)
  3. Full Date: calendarRound longCount
  4. Wildcards: * in any position (* Ajaw 8 Kumk'u, 9.*.10.10.10)
  5. Operations: expr (+ | -) expr
  6. Comments: # text (inline or standalone)
  7. Whitespace: Space, tab handling rules

Deliverables

1. docs/GRAMMAR.md

Create comprehensive grammar document with:

Introduction

  • Purpose of the grammar
  • Notation conventions (EBNF)
  • Reading guide for non-experts

Lexical Tokens

(* Terminals *)
NUMBER     ::= [0-9]+
WORD       ::= [a-zA-Z']+
WILDCARD   ::= '*'
PERIOD     ::= '.'
PLUS       ::= '+'
MINUS      ::= '-'
HASH       ::= '#'
NEWLINE    ::= '\n'
SPACE      ::= ' ' | '\t'

Syntactic Grammar

(* Main productions *)
input          ::= line (NEWLINE line)* NEWLINE?
line           ::= expression comment? | comment | ε

expression     ::= operation | fullDate | calendarRound | longCount

operation      ::= expression WS+ operator WS+ expression
operator       ::= PLUS | MINUS

fullDate       ::= calendarRound WS+ longCount

calendarRound  ::= tzolkin WS+ haab
tzolkin        ::= tzolkinCoeff WS+ tzolkinDay
tzolkinCoeff   ::= NUMBER | WILDCARD
tzolkinDay     ::= WORD | WILDCARD

haab           ::= haabCoeff WS+ haabMonth
haabCoeff      ::= NUMBER | WILDCARD
haabMonth      ::= WORD | WILDCARD

longCount      ::= lcPart (PERIOD lcPart)*
lcPart         ::= NUMBER | WILDCARD

comment        ::= HASH commentText
commentText    ::= [^\n]*

WS             ::= SPACE+

Semantic Constraints

Document validation rules not expressible in grammar:

  1. Tzolkin Coefficient: Must be 1-13 (if not wildcard)
  2. Tzolkin Day: Must be one of 20 valid day names (if not wildcard)
  3. Haab Coefficient: Must be 0-19 (if not wildcard), except Wayeb (0-4)
  4. Haab Month: Must be one of 19 valid month names (if not wildcard)
  5. Long Count Parts:
    • Baktun: Any non-negative integer
    • Katun, Tun, Winal, Kin: 0-19
    • Winal (position 1): Special base-18 rule
  6. Long Count Length: Must be 1-5 parts (partial dates allowed)

2. Examples for Each Production

For every grammar rule, provide 3+ examples:

#### `calendarRound` Examples

**Valid**:
- `4 Ajaw 8 Kumk'u` - Standard calendar round
- `* Ajaw 8 Kumk'u` - Wildcard tzolkin coefficient
- `4 * 8 Kumk'u` - Wildcard tzolkin day
- `4 Ajaw * Kumk'u` - Wildcard haab coefficient
- `4 Ajaw 8 *` - Wildcard haab month
- `** **` - All wildcards

**Invalid** (with explanation):
- `14 Ajaw 8 Kumk'u` - Tzolkin coefficient > 13
- `4 Ajaw 20 Kumk'u` - Haab coefficient > 19
- `4 NotADay 8 Kumk'u` - Unknown tzolkin day name

3. Ambiguity Analysis

Document and resolve ambiguities:

Ambiguity 1: Partial Dates

Issue: Is 4 Ajaw a valid partial calendar round (tzolkin only) or an error?

Current Behavior (from tests):

// layer-1 test shows this is NOT parsed as standalone tzolkin
'4 Ajaw' // Would need to check actual test behavior

Resolution: Document whether partial dates are:

  • Option A: Allowed (tzolkin-only or haab-only are valid)
  • Option B: Forbidden (must always have both parts or fail)

Ambiguity 2: Whitespace Handling

Issue: How much whitespace is required/allowed between components?

Examples:

  • 4 Ajaw 8 Kumk'u - Single space (valid)
  • 4 Ajaw 8 Kumk'u - Multiple spaces (valid?)
  • 4Ajaw 8Kumk'u - No space between number and word (valid?)

Current Behavior (from tests):

// From layer-0-parser.spec.ts line 137:
['6Manik\' 5Mol', [NT(6), WT('Manik\''), ST, NT(5), WT('Mol'), LET]]
// This suggests no space between number+word IS parsed

Resolution: Specify exact whitespace rules.

Ambiguity 3: Comment Placement

Issue: Can comments appear anywhere?

Examples:

  • 4 Ajaw 8 Kumk'u # comment - After full date (valid)
  • # comment\n4 Ajaw 8 Kumk'u - Standa...

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits January 5, 2026 08:29
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
…nces

Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Copilot AI changed the title [WIP] Document Maya date parsing grammar in EBNF notation Add formal EBNF grammar specification for Maya date parser Jan 5, 2026
Copilot AI requested a review from drewsonne January 5, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create Formal Grammar Specification

2 participants