Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

DONE Grammar Specification

The grammar is composed of production rules with syntactic meaning and attached typing rules conveying semantic information about the language.

The core data structures are defined in src/logic/grammar/mod.rs.

Production Rules

Production rules define the syntactic structure of the language. Each rule maps a nonterminal to one or more alternative right-hand sides.

Definition: Production Rule Syntax
Nonterminal(rule_name) ::= symbol₁ symbol₂ ... | alternative₂ | ...
  • Nonterminal: symbol being defined.
  • (rule_name): optional typing rule name.
  • ::=: separator.
  • |: alternative separator.
  • symbols: sequence of terminals and nonterminals.

Bindings are resolved via grammar paths during type-checking. See src/logic/binding/grammar.rs for the path construction algorithm.

Epsilon Productions

An epsilon production represents an empty alternative, written as ε.

// Optional tail matching zero or more Terms
ProgramTail ::= Term ProgramTail | ε

Typing Rules

Typing rules attach semantic information to productions using an inference-rule format.

premise₁, premise₂, ...
------------------------ (rule_name)
conclusion

The rule name in parentheses must match a (rule_name) annotation on a production.

Premises

Premises express conditions for rule application.

SyntaxMeaning
Γ ⊢ e : τTerm e has type τ in context Γ (inference)
Γ ▷ eCheck that term e is well-typed in context Γ (checking)
x ∈ ΓVariable x is bound in context Γ
τ₁ = τ₂Types must unify
τ₁ ⊆ τ₂Type τ₁ is a subtype of τ₂
Γ[x:τ]Extend context with binding x:τ

Conclusions

Conclusions specify the rule’s result:

SyntaxMeaning
τReturn type τ
Γ(x)Look up type of x in context
Γ → Γ[x:τ] ⊢ τSet type of x in context and return τ

Checking mode () is not implemented as a conclusion; use the check premise Γ ▷ e instead.

Meta-Variables

A meta-variable (written ?A, ?B, etc.) is a placeholder unified during type checking, allowing rules to express polymorphic constraints.

// ?A must unify with both the function's domain and the argument's type.
Γ ⊢ f : ?A → ?B, Γ ⊢ e : ?A
-------------------------------- (app)
?B

Context Operations

The typing context Γ maps variable names to types:

  • Γ(x): Look up type of variable x.
  • Γ[x:τ]: Extend context with binding x:τ.
  • x ∈ Γ: Check if x is bound in context.

Type Syntax

Types in typing rules follow this syntax:

SyntaxDescription
τType variable (from binding)
Not Type
?AMeta-variable (unified during checking)
'int'Raw/concrete type literal
τ₁ → τ₂Function type
τ₁ | τ₂Union type
Top type (any)
Bottom type (none)
Γ(x)Context lookup

Example: Simply-Typed Lambda Calculus

A complete specification for STLC from examples/stlc.auf:

// Identifier (supports Unicode)
Identifier ::= /[A-Za-z_][A-Za-z0-9]*/

// Variables with var typing rule
Variable(var) ::= Identifier[x]

TypeName ::= /[A-Za-z0-9_τ₁₂₃₄₅₆₇₈₉₀]+/

// Base types (parentheses are literals, hence quoted)
BaseType ::= TypeName | '(' Type ')'

// Function types (right-associative)
AtomicType ::= BaseType | '(' Type ')'
FunctionType ::= AtomicType '->' Type
Type ::= AtomicType | FunctionType

// Lambda abstraction (dot is a literal)
Lambda(lambda) ::= 'λ' Identifier[a] ':' Type[τ] '.' Expression[e]

// Atomic expressions
AtomicExpression ::= Variable | '(' Expression ')' | Lambda

// Applications (left-associative)
Application(app) ::= Expression[l] AtomicExpression[r]

// Expressions (start symbol)
Expression ::= AtomicExpression |  Application

// Typing Rules
x ∈ Γ
----------- (var)
Γ(x)

Γ[a:τ] ⊢ e : ?B
--------------------------- (lambda)
τ → ?B

Γ ⊢ l : ?A → ?B, Γ ⊢ r : ?A
--------------------------------- (app)
?B

Source Files

ComponentPath
Grammar structuressrc/logic/grammar/mod.rs
Spec file loadingsrc/logic/grammar/load.rs
Typing rulessrc/logic/typing/rule.rs
Type definitionssrc/logic/typing/mod.rs
Binding mapsrc/logic/binding/grammar.rs