X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=parser.l;h=82957eb41b19cd497b761c42cebb4580bddd6baf;hb=ca87afb87619efbaa94fe045670bc916e9ffe3ec;hp=e35de38fa351c75559cdb9a4083a43281ff8e541;hpb=056614196635a4730170261fe0e638191f14c620;p=xboard.git diff --git a/parser.l b/parser.l old mode 100644 new mode 100755 index e35de38..82957eb --- a/parser.l +++ b/parser.l @@ -7,10 +7,12 @@ %{ /* * parser.l -- lex parser of algebraic chess moves for XBoard - * $Id: parser.l,v 2.1 2003/10/27 19:21:00 mann Exp $ * - * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts. - * Enhancements Copyright 1992-95 Free Software Foundation, Inc. + * Copyright 1991 by Digital Equipment Corporation, Maynard, + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -34,28 +36,39 @@ * SOFTWARE. * ------------------------------------------------------------------------ * - * The following terms apply to the enhanced version of XBoard distributed - * by the Free Software Foundation: + * The following terms apply to the enhanced version of XBoard + * distributed by the Free Software Foundation: * ------------------------------------------------------------------------ - * This program is free software; you can redistribute it and/or modify + * + * GNU XBoard is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * ------------------------------------------------------------------------ - */ + * along with this program. If not, see http://www.gnu.org/licenses/. + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ /* This parser handles all forms of promotion. * The parser resolves ambiguous moves by searching and check-testing. * It also parses comments of the form [anything] or (anything). + * + * [HGM] Parser extensively modified for bigger boards, Shogi-like syntax, + * and unknow pieces. All pieces are now mandatory upper case, but can be + * any letter A-Z. Files must be lower case (as before), but can run upto 'l'. + * Ranks can be 0-9. The parser returns 0 for off-board files and ranks. + * For an unknown piece (as mover or promotion piece) it returns + * IllegalMove, like it does when the piece doesn't match. + * Promotions can now also be appended Shogi-style, a bare '=' or '+', + * and this is then returned as promotion character. The piece indicator + * can be prefixed by a '+' to indicate it is a promoted piece. */ #include "config.h" @@ -77,6 +90,16 @@ char *yy_text = (char *) yytext; #ifdef FLEX_SCANNER /* This is flex */ +/* [AP] use prototypes in function declarations */ +#define YY_USE_PROTOS + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif +/* end of [AP] fix */ + #undef YY_INPUT #define YY_INPUT(buf, result, max_size) my_yy_input(buf, &result, max_size) #undef YY_DECL @@ -155,25 +178,25 @@ extern void CopyBoard P((Board to, Board from)); %} %% -[RrBbNnQqKkPpACDEFGHMWO][/]?[a-l][0-9][xX:-]?[a-l][0-9](=?\(?[RrBbNnQqKkAaCc]\)?)? { +"+"?[A-Z][/]?[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|=)? { /* * Fully-qualified algebraic move, possibly with promotion - * [HGM] Bigger-than-8x8 boards must rely on long algebraic formats - * where I allowed piece types A & C (also as promotions) - * files a-l and ranks 0-9 */ - int skip1 = 0, skip2 = 0; + int skip1 = 0, skip2 = 0, skip3 = 0, promoted = 0; ChessSquare piece; ChessMove result; + char c; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + if (yytext[0] == '+') skip1 = skip3 = promoted = 1; /* [HGM] Shogi promoted */ + /* remove the / */ - if (yytext[1] == '/') skip1 = 1; + if (yytext[1+skip1] == '/') skip1++; /* remove the [xX:-] */ if ((yytext[3+skip1] == 'x') || (yytext[3+skip1] == 'X') || - (yytext[3+skip1] == '-') || (yytext[3+skip1] == ':')) skip2 = 1; + (yytext[3+skip1] == '-') || (yytext[3+skip1] == ':')) skip2 = 1; currentMoveString[0] = yytext[1+skip1]; currentMoveString[1] = yytext[2+skip1]; @@ -181,51 +204,68 @@ extern void CopyBoard P((Board to, Board from)); currentMoveString[3] = yytext[4+skip1+skip2]; currentMoveString[4] = NULLCHAR; - if (yyleng-skip1-skip2 > 5) { - if (yytext[yyleng-1] == ')') { - currentMoveString[4] = ToLower(yytext[yyleng-2]); + if (appData.debugMode) { + fprintf(debugFP, "Parser Qa1b2: yyleng=%d\n", + yyleng); + } + + if (yyleng-skip1-skip2 > 5) { char c; + if (yytext[yyleng-1] == ')') { + c = currentMoveString[4] = ToLower(yytext[yyleng-2]); } else { - currentMoveString[4] = ToLower(yytext[yyleng-1]); + c = currentMoveString[4] = ToLower(yytext[yyleng-1]); } currentMoveString[5] = NULLCHAR; + if(c != '=' && c != '+' && CharToPiece(c) == EmptySquare) + return IllegalMove; /* [HGM] promotion to invalid piece */ } + if (appData.debugMode) { + fprintf(debugFP, "parser: %s\n", currentMoveString); + } /* [HGM] do not allow values beyond board size */ if(currentMoveString[1] - ONE >= BOARD_HEIGHT || - currentMoveString[0] - 'a' >= BOARD_WIDTH || + currentMoveString[1] - ONE < 0 || + currentMoveString[0] - AAA >= BOARD_RGHT || currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[2] - 'a' >= BOARD_WIDTH ) + currentMoveString[3] - ONE < 0 || + currentMoveString[2] - AAA >= BOARD_RGHT || + currentMoveString[0] - AAA < BOARD_LEFT || + currentMoveString[2] - AAA < BOARD_LEFT ) return 0; piece = boards[yyboardindex] - [currentMoveString[1] - ONE][currentMoveString[0] - 'a']; - if (ToLower(yytext[0]) != ToLower(PieceToChar(piece))) + [currentMoveString[1] - ONE][currentMoveString[0] - AAA]; + if(promoted) piece = (ChessSquare) (DEMOTED piece); + c = PieceToChar(piece); + if(c == '~') c = PieceToChar((ChessSquare) (DEMOTED piece)); + if (ToLower(yytext[skip3]) != ToLower(c)) return (int) IllegalMove; result = LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex), EP_UNKNOWN, + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + EP_UNKNOWN, initialRights, /* [HGM] assume all castlings allowed */ currentMoveString[1] - ONE, - currentMoveString[0] - 'a', + currentMoveString[0] - AAA, currentMoveString[3] - ONE, - currentMoveString[2] - 'a', + currentMoveString[2] - AAA, currentMoveString[4]); if (currentMoveString[4] == NULLCHAR && - (result == WhitePromotionQueen || result == BlackPromotionQueen)) { - currentMoveString[4] = 'q'; + (result == WhitePromotionKnight || result == BlackPromotionKnight || + result == WhitePromotionQueen || result == BlackPromotionQueen)) { + currentMoveString[4] = PieceToChar(BlackQueen); currentMoveString[5] = NULLCHAR; } return (int) result; } -[a-l][0-9][xX:-]?[a-l][0-9](=?\(?[RrBbNnQqKkAaCc]\)?)? { +[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Za-z]\)?)|=)? { /* * Simple algebraic move, possibly with promotion - * [HGM] Bigger-than-8x8 boards must rely on this format - * where I allowed piece types A & C (also as promotions) - * files a-l and ranks 0-9 + * [HGM] Engine moves are received in this format, with lower-case promoChar! */ int skip = 0; ChessMove result; @@ -242,73 +282,90 @@ extern void CopyBoard P((Board to, Board from)); currentMoveString[3] = yytext[3+skip]; currentMoveString[4] = NULLCHAR; - if (yyleng-skip > 4) { + if (yyleng-skip > 4) { char c; if (yytext[yyleng-1] == ')') { - currentMoveString[4] = ToLower(yytext[yyleng-2]); + c = currentMoveString[4] = ToLower(yytext[yyleng-2]); } else { - currentMoveString[4] = ToLower(yytext[yyleng-1]); + c = currentMoveString[4] = ToLower(yytext[yyleng-1]); } currentMoveString[5] = NULLCHAR; + if(c != '=' && c != '+' && CharToPiece(c) == EmptySquare) + return IllegalMove; } /* [HGM] do not allow values beyond board size */ if(currentMoveString[1] - ONE >= BOARD_HEIGHT || - currentMoveString[0] - 'a' >= BOARD_WIDTH || + currentMoveString[1] - ONE < 0 || + currentMoveString[0] - AAA >= BOARD_RGHT || currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[2] - 'a' >= BOARD_WIDTH ) + currentMoveString[3] - ONE < 0 || + currentMoveString[2] - AAA >= BOARD_RGHT || + currentMoveString[0] - AAA < BOARD_LEFT || + currentMoveString[2] - AAA < BOARD_LEFT ) return 0; result = LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex), EP_UNKNOWN, + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + EP_UNKNOWN, initialRights, /* [HGM] assume all castlings allowed */ currentMoveString[1] - ONE, - currentMoveString[0] - 'a', + currentMoveString[0] - AAA, currentMoveString[3] - ONE, - currentMoveString[2] - 'a', + currentMoveString[2] - AAA, currentMoveString[4]); if (currentMoveString[4] == NULLCHAR && - (result == WhitePromotionQueen || result == BlackPromotionQueen)) { - currentMoveString[4] = 'q'; + (result == WhitePromotionKnight || result == BlackPromotionKnight || + result == WhitePromotionQueen || result == BlackPromotionQueen)) { + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier) + currentMoveString[4] = PieceToChar(BlackFerz); + else if(gameInfo.variant == VariantGreat) + currentMoveString[4] = PieceToChar(BlackMan); + else + currentMoveString[4] = PieceToChar(BlackQueen); currentMoveString[5] = NULLCHAR; } return (int) result; } -[a-l][0-9](=?\(?[RrBbNnQqKkAaCc]\)?)? { +[a-l][0-9]((=?\(?[A-Z]\)?)|=)? { /* * Pawn move, possibly with promotion */ DisambiguateClosure cl; - int skip = 0; + int skip = 0; char c; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ /* remove the =() */ - if (yytext[2] == '=') skip++; + if (yytext[2] == '=' && yytext[3] != NULLCHAR) skip++; if (yytext[2+skip] == '(') skip++; cl.pieceIn = WhiteOnMove(yyboardindex) ? WhitePawn : BlackPawn; cl.rfIn = -1; - cl.ffIn = yytext[0] - 'a'; + cl.ffIn = yytext[0] - AAA; cl.rtIn = yytext[1] - ONE; - cl.ftIn = yytext[0] - 'a'; - cl.promoCharIn = yytext[2+skip]; + cl.ftIn = yytext[0] - AAA; + c = cl.promoCharIn = yytext[2+skip]; /* [HGM] do not allow values beyond board size */ if(cl.rtIn >= BOARD_HEIGHT || - cl.ffIn >= BOARD_WIDTH || - cl.ftIn >= BOARD_WIDTH ) + cl.rtIn < 0 || + cl.ffIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) return 0; + if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare) + return IllegalMove; + Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), EP_UNKNOWN, &cl); - currentMoveString[0] = cl.ff + 'a'; + currentMoveString[0] = cl.ff + AAA; currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + 'a'; + currentMoveString[2] = cl.ft + AAA; currentMoveString[3] = cl.rt + ONE; currentMoveString[4] = cl.promoChar; currentMoveString[5] = NULLCHAR; @@ -317,12 +374,12 @@ extern void CopyBoard P((Board to, Board from)); } -(ab|bc|cd|de|ef|fg|gh|hi|ij|jk|kl|lk|kj|ji|ih|hg|gf|fe|ed|dc|cb|ba|aa|bb|cc|dd|ee|ff|gg|hh|ii|jj|kk|ll|([a-l][xX:-][a-l]))(=?\(?[RrBbNnQqKkAaCc]\)?)?(ep|"e.p.")? { +(ab|bc|cd|de|ef|fg|gh|hi|ij|jk|kl|lk|kj|ji|ih|hg|gf|fe|ed|dc|cb|ba|aa|bb|cc|dd|ee|ff|gg|hh|ii|jj|kk|ll|([a-l][xX:-][a-l]))((=?\(?[A-Z]\)?)|ep|"e.p."|=)? { /* * Pawn capture, possibly with promotion, possibly ambiguous */ DisambiguateClosure cl; - int skip1 = 0, skip2 = 0; + int skip1 = 0, skip2 = 0; char c; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ @@ -338,27 +395,32 @@ extern void CopyBoard P((Board to, Board from)); /* remove the [xX:-] and =() */ if ((yytext[1] == 'x') || (yytext[1] == 'X') || (yytext[1] == ':') || (yytext[1] == '-')) skip1 = 1; - if (yytext[2+skip1] == '=') skip2++; + if (yytext[2+skip1] == '=' && yytext[3+skip1] != NULLCHAR) skip2++; if (yytext[2+skip1+skip2] == '(') skip2++; cl.pieceIn = WhiteOnMove(yyboardindex) ? WhitePawn : BlackPawn; cl.rfIn = -1; - cl.ffIn = yytext[0] - 'a'; + cl.ffIn = yytext[0] - AAA; cl.rtIn = -1; - cl.ftIn = yytext[1+skip1] - 'a'; - cl.promoCharIn = yytext[2+skip1+skip2]; + cl.ftIn = yytext[1+skip1] - AAA; + c = cl.promoCharIn = yytext[2+skip1+skip2]; /* [HGM] do not allow values beyond board size */ - if(cl.ffIn >= BOARD_WIDTH || - cl.ftIn >= BOARD_WIDTH ) + if(cl.ffIn >= BOARD_RGHT || + cl.ffIn < BOARD_LEFT || + cl.ftIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) return 0; + if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare) + return IllegalMove; + Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), EP_UNKNOWN, &cl); - currentMoveString[0] = cl.ff + 'a'; + currentMoveString[0] = cl.ff + AAA; currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + 'a'; + currentMoveString[2] = cl.ft + AAA; currentMoveString[3] = cl.rt + ONE; currentMoveString[4] = cl.promoChar; currentMoveString[5] = NULLCHAR; @@ -366,12 +428,12 @@ extern void CopyBoard P((Board to, Board from)); return (int) cl.kind; } -[a-l][xX:]?[a-l][0-9](=?\(?[RrBbNnQqKkAaCc]\)?)?(ep|"e.p.")? { +[a-l][xX:]?[a-l][0-9]((=?\(?[A-Z]\)?)|ep|"e.p."|=)? { /* * unambiguously abbreviated Pawn capture, possibly with promotion */ int skip = 0; - ChessMove result; + ChessMove result; char c; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ @@ -393,45 +455,60 @@ extern void CopyBoard P((Board to, Board from)); currentMoveString[3] = yytext[2+skip]; /* [HGM] do not allow values beyond board size */ - if(currentMoveString[0] - 'a' >= BOARD_WIDTH || + if(currentMoveString[0] - AAA >= BOARD_RGHT || currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[2] - 'a' >= BOARD_WIDTH ) + currentMoveString[3] - ONE < 0 || + currentMoveString[2] - AAA >= BOARD_RGHT || + currentMoveString[0] - AAA < BOARD_LEFT || + currentMoveString[2] - AAA < BOARD_LEFT ) return 0; if (gameInfo.variant == VariantXiangqi && /* [HGM] In Xiangqi rank stays same */ currentMoveString[0] != currentMoveString[2] ) { - if (yytext[2+skip] == ONE) return (int) ImpossibleMove; currentMoveString[1] = yytext[2+skip]; } else if (WhiteOnMove(yyboardindex)) { if (yytext[2+skip] == ONE) return (int) ImpossibleMove; currentMoveString[1] = yytext[2+skip] - 1; + if(boards[yyboardindex][currentMoveString[1]-ONE][currentMoveString[0]-AAA] != WhitePawn) + return ImpossibleMove; } else { currentMoveString[1] = currentMoveString[3] + 1; if (currentMoveString[3] == ONE+BOARD_HEIGHT-1) return (int) ImpossibleMove; + if(boards[yyboardindex][currentMoveString[1]-ONE][currentMoveString[0]-AAA] != BlackPawn) + return ImpossibleMove; } if (yyleng-skip > 3) { if (yytext[yyleng-1] == ')') - currentMoveString[4] = ToLower(yytext[yyleng-2]); + c = currentMoveString[4] = ToLower(yytext[yyleng-2]); else - currentMoveString[4] = ToLower(yytext[yyleng-1]); + c = currentMoveString[4] = ToLower(yytext[yyleng-1]); currentMoveString[5] = NULLCHAR; + if(c != '=' && c != '+' && CharToPiece(c) == EmptySquare) + return IllegalMove; } else { currentMoveString[4] = NULLCHAR; } result = LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex), EP_UNKNOWN, + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + EP_UNKNOWN, initialRights, /* [HGM] assume all castlings allowed */ currentMoveString[1] - ONE, - currentMoveString[0] - 'a', + currentMoveString[0] - AAA, currentMoveString[3] - ONE, - currentMoveString[2] - 'a', + currentMoveString[2] - AAA, currentMoveString[4]); if (currentMoveString[4] == NULLCHAR && - (result == WhitePromotionQueen || result == BlackPromotionQueen)) { - currentMoveString[4] = 'q'; + (result == WhitePromotionQueen || result == BlackPromotionQueen || + result == WhitePromotionKnight || result == BlackPromotionKnight)) { + currentMoveString[4] = PieceToChar(BlackQueen); + // [HGM] shatranj: take care of variants without Queen + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier) + currentMoveString[4] = PieceToChar(BlackFerz); + if(gameInfo.variant == VariantGreat) + currentMoveString[4] = PieceToChar(BlackMan); currentMoveString[5] = NULLCHAR; } @@ -455,12 +532,13 @@ extern void CopyBoard P((Board to, Board from)); } result = LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex), EP_UNKNOWN, + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + EP_UNKNOWN, initialRights, /* [HGM] assume all castlings allowed */ currentMoveString[1] - ONE, - currentMoveString[0] - 'a', + currentMoveString[0] - AAA, currentMoveString[3] - ONE, - currentMoveString[2] - 'a', + currentMoveString[2] - AAA, currentMoveString[4]); if (result == WhiteCapturesEnPassant || result == BlackCapturesEnPassant) @@ -469,41 +547,56 @@ extern void CopyBoard P((Board to, Board from)); return (int) IllegalMove; } -[RrBbNnQqKkACDEFGHMWO][xX:-]?[a-l][0-9] { +"+"?[A-Z][xX:-]?[a-l][0-9]=? { /* * piece move, possibly ambiguous */ DisambiguateClosure cl; - int skip = 0; + int skip = 0, skip2 = 0, promoted = 0; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + if(yytext[0] == '+') promoted = skip = skip2 = 1; + /* remove the [xX:-] */ - if ((yytext[1] == 'x') || (yytext[1] == 'X') - || (yytext[1] == ':') || (yytext[1] == '-')) skip = 1; + if ((yytext[1+skip] == 'x') || (yytext[1+skip] == 'X') + || (yytext[1+skip] == ':') || (yytext[1+skip] == '-')) skip++; if (WhiteOnMove(yyboardindex)) { - cl.pieceIn = CharToPiece(ToUpper(yytext[0])); + cl.pieceIn = CharToPiece(ToUpper(yytext[skip2])); } else { - cl.pieceIn = CharToPiece(ToLower(yytext[0])); + cl.pieceIn = CharToPiece(ToLower(yytext[skip2])); } + if(promoted) cl.pieceIn = (ChessSquare) (PROMOTED cl.pieceIn); + cl.rfIn = -1; cl.ffIn = -1; cl.rtIn = yytext[2+skip] - ONE; - cl.ftIn = yytext[1+skip] - 'a'; + cl.ftIn = yytext[1+skip] - AAA; cl.promoCharIn = NULLCHAR; + if(yyleng-skip > 3) /* [HGM] can have Shogi-style promotion */ + cl.promoCharIn = yytext[yyleng-1]; + + if (appData.debugMode) { + fprintf(debugFP, "Parser Qa1: yyleng=%d, %d(%d,%d)-(%d,%d) = %d (%c)\n", + yyleng, + cl.pieceIn,cl.ffIn,cl.rfIn,cl.ftIn,cl.rtIn,cl.promoCharIn,cl.promoCharIn?cl.promoCharIn:' '); + } + /* [HGM] but do not allow values beyond board size */ if(cl.rtIn >= BOARD_HEIGHT || - cl.ftIn >= BOARD_WIDTH ) + cl.rtIn < 0 || + cl.ftIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) return 0; Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), EP_UNKNOWN, &cl); - currentMoveString[0] = cl.ff + 'a'; + currentMoveString[0] = cl.ff + AAA; currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + 'a'; + currentMoveString[2] = cl.ft + AAA; currentMoveString[3] = cl.rt + ONE; currentMoveString[4] = cl.promoChar; currentMoveString[5] = NULLCHAR; @@ -511,48 +604,60 @@ extern void CopyBoard P((Board to, Board from)); return (int) cl.kind; } -[RrBbNnQqKkACDEFGHMWO][a-l0-9][xX:-]?[a-l][0-9] { +"+"?[A-Z][a-l0-9][xX:-]?[a-l][0-9]=? { /* * piece move with rank or file disambiguator */ DisambiguateClosure cl; - int skip = 0; + int skip = 0, skip2 = 0; int promoted=0; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + if(yytext[0]=='+') promoted = skip = skip2 = 1; + /* remove the [xX:-] */ - if ((yytext[2] == 'x') || (yytext[2] == 'X') - || (yytext[2] == ':') || (yytext[2] == '-')) skip = 1; + if ((yytext[2+skip] == 'x') || (yytext[2+skip] == 'X') + || (yytext[2+skip] == ':') || (yytext[2+skip] == '-')) skip++; if (WhiteOnMove(yyboardindex)) { - cl.pieceIn = CharToPiece(ToUpper(yytext[0])); + cl.pieceIn = CharToPiece(ToUpper(yytext[skip2])); } else { - cl.pieceIn = CharToPiece(ToLower(yytext[0])); + cl.pieceIn = CharToPiece(ToLower(yytext[skip2])); } - if (isalpha(yytext[1])) { + if(promoted) cl.pieceIn = (ChessSquare) (PROMOTED cl.pieceIn); + + if (isalpha(yytext[1+skip2])) { cl.rfIn = -1; - cl.ffIn = yytext[1] - 'a'; + cl.ffIn = yytext[1+skip2] - AAA; + + if(cl.ffIn >= BOARD_RGHT || + cl.ffIn < BOARD_LEFT ) return 0; } else { - cl.rfIn = yytext[1] - ONE; + cl.rfIn = yytext[1+skip2] - ONE; cl.ffIn = -1; + if(cl.rfIn >= BOARD_HEIGHT || + cl.rfIn < 0) return 0; } cl.rtIn = yytext[3+skip] - ONE; - cl.ftIn = yytext[2+skip] - 'a'; + cl.ftIn = yytext[2+skip] - AAA; cl.promoCharIn = NULLCHAR; + if(yyleng-skip > 4) /* [HGM] can have Shogi-style promotion */ + cl.promoCharIn = yytext[yyleng-1]; + /* [HGM] do not allow values beyond board size */ if(cl.rtIn >= BOARD_HEIGHT || - cl.rfIn >= BOARD_HEIGHT || - cl.ffIn >= BOARD_WIDTH || - cl.ftIn >= BOARD_WIDTH ) + cl.rtIn < 0 || + cl.ftIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) return 0; Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), EP_UNKNOWN, &cl); - currentMoveString[0] = cl.ff + 'a'; + currentMoveString[0] = cl.ff + AAA; currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + 'a'; + currentMoveString[2] = cl.ft + AAA; currentMoveString[3] = cl.rt + ONE; currentMoveString[4] = cl.promoChar; currentMoveString[5] = NULLCHAR; @@ -572,34 +677,46 @@ extern void CopyBoard P((Board to, Board from)); rf = 0; ff = (BOARD_WIDTH-1)>>1; rt = 0; - ft = BOARD_WIDTH-3; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_RGHT-3; } else { rf = 0; ff = BOARD_WIDTH>>1; rt = 0; - ft = 2; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_LEFT+2; } } else{ - if (boards[yyboardindex][BOARD_HEIGHT-1][3] == BlackKing) { + if (boards[yyboardindex][BOARD_HEIGHT-1][(BOARD_WIDTH-1)>>1] == BlackKing) { /* ICS wild castling */ rf = BOARD_HEIGHT-1; ff = (BOARD_WIDTH-1)>>1; rt = BOARD_HEIGHT-1; - ft = BOARD_WIDTH-3; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_RGHT-3; } else { rf = BOARD_HEIGHT-1; ff = BOARD_WIDTH>>1; rt = BOARD_HEIGHT-1; - ft = 2; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_LEFT+2; } } + if(gameInfo.variant == VariantFischeRandom) { + if (WhiteOnMove(yyboardindex)) { + ff = initialRights[2]; + ft = initialRights[1]; + } else { + ff = initialRights[5]; + ft = initialRights[4]; + } + fprintf(debugFP, "Parser FRC long %d %d\n", ff, ft); + if(ff < 0 || ft < 0) return 0; + } + sprintf(currentMoveString, "%c%c%c%c",ff+AAA,rf+ONE,ft+AAA,rt+ONE); + if (appData.debugMode) { + fprintf(debugFP, "long castling %d %d\n", ff, ft); + } return (int) LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex), EP_UNKNOWN, - initialRights, /* [HGM] assume all castlings allowed */ + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.! + EP_UNKNOWN, + castlingRights[yyboardindex], /* [HGM] use true castling rights */ rf, ff, rt, ft, NULLCHAR); } @@ -614,14 +731,12 @@ extern void CopyBoard P((Board to, Board from)); rf = 0; ff = (BOARD_WIDTH-1)>>1; rt = 0; - ft = 1; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_LEFT+1; } else { rf = 0; ff = BOARD_WIDTH>>1; rt = 0; - ft = BOARD_WIDTH-2; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_RGHT-2; } } else { if (boards[yyboardindex][BOARD_HEIGHT-1][(BOARD_WIDTH-1)>>1] == BlackKing) { @@ -629,34 +744,52 @@ extern void CopyBoard P((Board to, Board from)); rf = BOARD_HEIGHT-1; ff = (BOARD_WIDTH-1)>>1; rt = BOARD_HEIGHT-1; - ft = 1; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_LEFT+1; } else { rf = BOARD_HEIGHT-1; ff = BOARD_WIDTH>>1; rt = BOARD_HEIGHT-1; - ft = BOARD_WIDTH-2; - sprintf(currentMoveString, "%c%c%c%c",ff+'a',rf+ONE,ft+'a',rt+ONE); + ft = BOARD_RGHT-2; } } + if(gameInfo.variant == VariantFischeRandom) { + if (WhiteOnMove(yyboardindex)) { + ff = initialRights[2]; + ft = initialRights[0]; + } else { + ff = initialRights[5]; + ft = initialRights[3]; + } + if (appData.debugMode) { + fprintf(debugFP, "Parser FRC short %d %d\n", ff, ft); + } + if(ff < 0 || ft < 0) return 0; + } + sprintf(currentMoveString, "%c%c%c%c",ff+AAA,rf+ONE,ft+AAA,rt+ONE); + if (appData.debugMode) { + fprintf(debugFP, "short castling %d %d\n", ff, ft); + } + return (int) LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex), EP_UNKNOWN, - initialRights, /* [HGM] assume all castlings allowed */ + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.! + EP_UNKNOWN, + castlingRights[yyboardindex], /* [HGM] use true castling rights */ rf, ff, rt, ft, NULLCHAR); } -[PpNnBbRrQqAaCc]@[a-l][0-9] { +[A-Z][@*][a-l][0-9] { /* Bughouse piece drop. No legality checking for now. */ currentMoveString[1] = '@'; currentMoveString[2] = yytext[2]; currentMoveString[3] = yytext[3]; currentMoveString[4] = NULLCHAR; + if (appData.debugMode) { + fprintf(debugFP, "Drop: %s\n", currentMoveString); + } /* [HGM] do not allow values beyond board size */ - if(currentMoveString[1] - ONE >= BOARD_HEIGHT || - currentMoveString[0] - 'a' >= BOARD_WIDTH || - currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[2] - 'a' >= BOARD_WIDTH ) + if(currentMoveString[3] - ONE >= BOARD_HEIGHT || + currentMoveString[2] - AAA >= BOARD_WIDTH ) return 0; if (WhiteOnMove(yyboardindex)) { @@ -930,9 +1063,9 @@ static YY_BUFFER_STATE my_file_buffer = NULL; */ int yyoffset() { - int pos = yy_c_buf_p - yy_current_buffer->yy_ch_buf; + int pos = yy_c_buf_p - YY_CURRENT_BUFFER->yy_ch_buf; - return(ftell(yy_current_buffer->yy_input_file) - + return(ftell(YY_CURRENT_BUFFER->yy_input_file) - yy_n_chars + pos); }