Skip to content

Instantly share code, notes, and snippets.

@dseg
Created March 8, 2016 14:33
Show Gist options
  • Save dseg/2c52d22d163b4ae3a231 to your computer and use it in GitHub Desktop.
Save dseg/2c52d22d163b4ae3a231 to your computer and use it in GitHub Desktop.
sfen-parser.pegjs
/**
* Title: SFEN parser
* Date: 23-Jan-2014
* Author: Daichi Shinozaki <dsdseg@gmail.com>
* Demo URL: http://jsfiddle.net/dseg/QezQ7/15/
*
* Note:
* Tested with PEG.js 0.8.0
* http://pegjs.majda.cz/
*
* SFEN stands for 'Shogi FEN'
* http://www.glaurungchess.com/shogi/usi.html
*
* FEN stands for 'Forsyth-Edwards Notation', a standard notation for describing a
* particular board position of a chess game.
* http://en.wikipedia.org/wiki/Forsyth-Edwards_Notation
*
* A complicated SFEN example is the following position, taken from the 3rd game of the
* 19th Ryu-O match between Sato and Watanabe:
*
* 8l/1l+R2P3/p2pBG1pp/kps1p4/Nn1P2G2/P1P1P2PP/1PS6/1KSG3+r1/LN2+p3L w Sbgn3p 124
*
* http://live.shogi.or.jp/ryuou/kifu_archives/kifu_19/061115_watanabe-sato.html
* http://live.shogi.or.jp/ryuou/kifu_archives/kifu_19/061115_ryuoh.kif
*/
/* utility function */
{
function flatten(array) {
var merged = [];
return merged.concat.apply(merged, array);
}
}
start
= board:boardState " " side:theSideToMove " " piecesInHand:piecesInHand " " moves:moveCount {
var boardFlattened = flatten(board);
var pihFlattened = flatten(piecesInHand);
return { board:boardFlattened, side:side, piecesInHand:pihFlattened, moves:moves }
}
boardState
= first:row rest:("/" row)+ {
var result = [];
for (var i = 0; i < rest.length; i++)
result = result.concat(rest[i][1]); // skip heading '/'
return first.concat(result);
}
row
= (digit:digit {
var digitConverted = [];
while (digit-- > 0)
digitConverted.push(" ");
return digitConverted;
}
/ piece:piece)+
digit
= [1-9]
piece
= $(promotion? [lnsgkprbLNSGKPRB])
promotion
= "+"
theSideToMove
= [bw]
digit2to9
= [2-9]
/* '-' means 'no pieces in hand' */
pieceInHand
= [lnsgprbLNSGPRB-]
piecesInHand
= (p:pieceInHand count:digit2to9 {
var pieces = [];
while(count-- > 0)
pieces.push(p);
return pieces;
}
/ pieceInHand)+
moveCount
= integer
integer
= integer:$[0-9]+ { return parseInt(integer); }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment