chess-lab 0.2.1

Chess library with multiple variants and FEN/PGN support.
Documentation
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
COMMENT    =  { "{" ~ (!"}" ~ ANY)* ~ "}" }

// Constants
key           = @{ (!("]" | "\"") ~ ASCII_ALPHA)+ }
value         = @{ (!("]" | "\"") ~ ANY)+ }
file          = @{ 'a'..'h' }
rank          = @{ '1'..'8' }
piece         = @{ ("K" | "Q" | "R" | "B" | "N") }
square        = @{ file ~ rank }
option_square = @{ file? ~ rank? }

// Move information
check_state        = @{ ("+" | "#") }
promotion          = @{ "=" ~ (!"K" ~ piece) }
castle             = @{ ("O-O-O" | "O-O") }
move_number        = @{ ('1'..'9') ~ ('0'..'9')* ~ "." }
second_move_number = @{ move_number ~ ".." }

// Move types
basic_move = @{ piece? ~ ((option_square ~ square) | square) }
capture    = @{ (square | file | rank | (piece ~ option_square)) ~ "x" ~ square }
move       = @{ (((capture | basic_move) ~ promotion?) | castle) ~ check_state? }

// Move sequences
partial_move = { move_number ~ move }
full_move    = { move_number ~ move{2} }
half_move    = { second_move_number ~ move }
line         = { (full_move* ~ partial_move) | full_move+ }

// Metadata
metadata = ${ "[" ~ key ~ " \"" ~ value? ~ "\"]" }
result   =  { "1/2-1/2" | "1-0" | "0-1" }

// Sequences
sequence               = {
    white_sequence
  | black_sequence
  | line
}
subsequence            = { "(" ~ sequence ~ ")" }
half_sequence          = { (half_move | move) ~ sequence? }
half_subsequence       = { "(" ~ half_sequence ~ ")" }
multi_subsequence      = { subsequence+ }
multi_half_subsequence = { half_subsequence+ }
white_sequence         = { (full_move* ~ partial_move) ~ multi_subsequence ~ half_sequence? }
black_sequence         = { (full_move+ ~ multi_half_subsequence ~ sequence?) }

// PGN
pgn      = !{ metadata* ~ sequence ~ result? }
pgn_file = ${ SOI ~ WHITESPACE* ~ pgn ~ (WHITESPACE* ~ pgn)* ~ WHITESPACE* ~ EOI }