Pular para o conteúdo
Untzel
Estreia 09.10
Páginas da documentação

Gramática

A gramática normativa é a gramática Lezer da qual o analisador do app é gerado. As palavras-chave estendem nomes, então sine: e loop: continuam sendo nomes de faixa válidos, e uma faixa sem padrão é aceita pela gramática e depois falha com EMPTY_PATTERN.

// Normative Lezer grammar of the Untzel language (docs/design/phase-1-sound.md, with
// the additions of docs/design/instruments.md).
// docs/03-linguagem.md describes the same language in informal EBNF; the conformance
// test keeps the two in agreement.

@top Source { (Line? newline)* Line? }

Line { TitleStatement | TempoStatement | KeyStatement | SwingStatement | LoopStatement | Track | SectionDecl | SongDecl }

TitleStatement { kw<"title"> String }
TempoStatement { kw<"tempo"> Number }
KeyStatement { kw<"key"> Tonic Name }
SwingStatement { kw<"swing"> Number }
LoopStatement { kw<"loop"> Number }

Track { (TrackName ":")? InstrumentName Preset? Pattern? ("|" Modifier)* }

Preset { PresetName }
TrackName { Name }
InstrumentName { Name }

SectionDecl { kw<"section"> Name Name+ ("|" Modifier)* }
SongDecl { kw<"song"> Part ("," Part)* ("|" kw<"loop">)? }
Part { Name Number }

Pattern { Bar ("/" Bar)* }
Bar { Element+ }
Element { Atom Accent? Probability? Repeat? }

Accent { "!" }
Probability { "?" Number? }
Repeat { "*" Number }
Atom { Hits | Note | Stack | Chord | Sustain | Group }

Stack { Note ("+" Note)+ }
Group { "[" Element+ "]" }

Modifier { ModifierName Value? }
ModifierName { Name | kw<"swing"> | kw<"tempo"> }
Value { Number | Signal Range? | Division | Name }
Signal { SignalShape "(" (Number | Division) ")" }
SignalShape { kw<"sine"> | kw<"tri"> | kw<"saw"> | kw<"square"> | kw<"rand"> | kw<"env"> }
Range { Number ".." Number }
Division { Number "/" Number }

kw<term> { @extend[@name={term}]<Name, term> }

@skip { space | Comment }

@tokens {
  space { $[ \t]+ }
  newline { "\r"? "\n" }
  Comment { "//" ![\n]* }
  Number { "-"? @digit+ ("." @digit+)? }
  // The song title: one line, \" and \\ are the only escapes.
  String { '"' (![\\\n"] | "\\" $["\\])* '"' }
  Name { $[a-z] $[a-z0-9_\-]* }
  Hits { $[xX.] $[xX.~]* }
  Sustain { "~" }
  Note { $[a-g] $[b#]? @digit }
  Tonic { $[a-g] $[b#]? }
  // A preset never starts with "x" (a hit) nor reads like a note or a tonic.
  PresetName { $[h-wyz] $[a-z0-9\-]* | $[a-g] $[ac-z\-] $[a-z0-9\-]* | $[a-g] "b" $[a-z\-] $[a-z0-9\-]* }
  Chord { $[A-G] $[b#]? ("maj7" | "m7" | "m" | "7" | "sus2" | "sus4" | "dim" | "6" | "m6" | "9"
          | "m9" | "maj9" | "add9" | "madd9" | "aug" | "dim7" | "m7b5" | "7sus4" | "11" | "m11" | "13")? }
  @precedence { Comment, "/" }
  ":" "|" "," "/" "?" "*" "[" "]" "(" ")" ".." "!" "+"
}
untzel.grammar, a gramática Lezer normativa

Conteúdo da documentação do Untzel, sob a licença CPAL-1.0. Ler a licença