X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=parser.c;h=804362a8bf740c1041284f4f0130d6b3b9063c02;hb=88082a3882690efd9ea7d3e01ad9d6dd5f5baf86;hp=ca1681b7a91fe4f1b72681f8bdeb620c65e8b035;hpb=ccc569b6febbb39ba6e7979f0068c04653456059;p=xboard.git diff --git a/parser.c b/parser.c index ca1681b..804362a 100644 --- a/parser.c +++ b/parser.c @@ -1718,176 +1718,176 @@ goto find_rule; \ char *yytext; #line 1 "parser.l" #line 8 "parser.l" -/* - * parser.l -- lex parser of algebraic chess moves for XBoard - * - * 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: - * ------------------------------------------------------------------------ - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of Digital not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * ------------------------------------------------------------------------ - * - * The following terms apply to the enhanced version of XBoard - * distributed by the Free Software Foundation: - * ------------------------------------------------------------------------ - * - * 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 3 of the License, or (at - * your option) any later version. - * - * 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, 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" - -#define NO_CONSTRAINT -1 -#undef YYLMAX -#define YYLMAX 4096 -#define UNPUT_BUF_SIZE YYLMAX - -#ifdef FLEX_SCANNER -/* yytext is probably a char*, but could be a char[]. yy_text is set - in YY_DECL below, because if yytext is a char*, its value is not - constant. */ -char *yy_text; -#else /*!FLEX_SCANNER*/ -/* yytext is definitely a char[], so yy_text can be set here, statically. */ -char *yy_text = (char *) yytext; -#endif - -#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 -#define YY_DECL \ - int _yylex YY_PROTO((void)); \ - int yylex YY_PROTO((void)) \ - { \ - int result = _yylex(); \ - yy_text = (char *) yytext; \ - return(result); \ - } \ - int _yylex YY_PROTO((void)) -#else -/* This is lex */ -#undef input -#undef output -#undef unput -#endif - -/* The includes must be here, below the #undef input */ - -#include - -#if STDC_HEADERS -# include -# include -#else /* not STDC_HEADERS */ -# if HAVE_STRING_H -# include -# else /* not HAVE_STRING_H */ -# include -# endif /* not HAVE_STRING_H */ -#endif /* not STDC_HEADERS */ - -#if HAVE_UNISTD_H -# include -#endif - -#if defined(_amigados) -# include -# if HAVE_FCNTL_H -# include /* isatty() prototype */ -# endif /* HAVE_FCNTL_H */ -#endif /* defined(_amigados) */ - -#include "common.h" -#include "backend.h" -#include "frontend.h" -#include "parser.h" -#include "moves.h" - -extern int PosFlags P((int)); - -extern Board boards[MAX_MOVES]; -int yyboardindex; -int yyskipmoves = FALSE; -char currentMoveString[YYLMAX]; -#ifndef FLEX_SCANNER -char unputBuffer[UNPUT_BUF_SIZE]; -int unputCount = 0; -#endif - -#ifdef FLEX_SCANNER -void my_yy_input P((char *buf, int *result, int max_size)); -#else /*!FLEX_SCANNER*/ -static int input P((void)); -static void output P((int ch)); -static void unput P((int ch)); -int yylook P((void)); -int yyback P((int *, int)); -#endif -#undef yywrap -int yywrap P((void)); -extern void CopyBoard P((Board to, Board from)); - +/* + * parser.l -- lex parser of algebraic chess moves for XBoard + * + * 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: + * ------------------------------------------------------------------------ + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Digital not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * ------------------------------------------------------------------------ + * + * The following terms apply to the enhanced version of XBoard + * distributed by the Free Software Foundation: + * ------------------------------------------------------------------------ + * + * 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 3 of the License, or (at + * your option) any later version. + * + * 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, 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" + +#define NO_CONSTRAINT -1 +#undef YYLMAX +#define YYLMAX 4096 +#define UNPUT_BUF_SIZE YYLMAX + +#ifdef FLEX_SCANNER +/* yytext is probably a char*, but could be a char[]. yy_text is set + in YY_DECL below, because if yytext is a char*, its value is not + constant. */ +char *yy_text; +#else /*!FLEX_SCANNER*/ +/* yytext is definitely a char[], so yy_text can be set here, statically. */ +char *yy_text = (char *) yytext; +#endif + +#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 +#define YY_DECL \ + int _yylex YY_PROTO((void)); \ + int yylex YY_PROTO((void)) \ + { \ + int result = _yylex(); \ + yy_text = (char *) yytext; \ + return(result); \ + } \ + int _yylex YY_PROTO((void)) +#else +/* This is lex */ +#undef input +#undef output +#undef unput +#endif + +/* The includes must be here, below the #undef input */ + +#include + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +# if HAVE_STRING_H +# include +# else /* not HAVE_STRING_H */ +# include +# endif /* not HAVE_STRING_H */ +#endif /* not STDC_HEADERS */ + +#if HAVE_UNISTD_H +# include +#endif + +#if defined(_amigados) +# include +# if HAVE_FCNTL_H +# include /* isatty() prototype */ +# endif /* HAVE_FCNTL_H */ +#endif /* defined(_amigados) */ + +#include "common.h" +#include "backend.h" +#include "frontend.h" +#include "parser.h" +#include "moves.h" + +extern int PosFlags P((int)); + +extern Board boards[MAX_MOVES]; +int yyboardindex; +int yyskipmoves = FALSE; +char currentMoveString[YYLMAX]; +#ifndef FLEX_SCANNER +char unputBuffer[UNPUT_BUF_SIZE]; +int unputCount = 0; +#endif + +#ifdef FLEX_SCANNER +void my_yy_input P((char *buf, int *result, int max_size)); +#else /*!FLEX_SCANNER*/ +static int input P((void)); +static void output P((int ch)); +static void unput P((int ch)); +int yylook P((void)); +int yyback P((int *, int)); +#endif +#undef yywrap +int yywrap P((void)); +extern void CopyBoard P((Board to, Board from)); + #line 1892 "parser.c" #define INITIAL 0 @@ -2046,7 +2046,7 @@ YY_DECL #line 179 "parser.l" - + #line 2051 "parser.c" if ( !(yy_init) ) @@ -2163,162 +2163,169 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP #line 181 "parser.l" -{ - /* - * Fully-qualified algebraic move, possibly with promotion - */ - 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] == '/') skip1++; - - /* remove the [xX:-] */ - if ((yytext[3+skip1] == 'x') || (yytext[3+skip1] == 'X') || - (yytext[3+skip1] == '-') || (yytext[3+skip1] == ':')) skip2 = 1; - - currentMoveString[0] = yytext[1+skip1]; - currentMoveString[1] = yytext[2+skip1]; - currentMoveString[2] = yytext[3+skip1+skip2]; - currentMoveString[3] = yytext[4+skip1+skip2]; - currentMoveString[4] = NULLCHAR; - - 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 { - 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[1] - ONE < 0 || - currentMoveString[0] - AAA >= BOARD_RGHT || - currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[3] - ONE < 0 || - currentMoveString[2] - AAA >= BOARD_RGHT || - currentMoveString[0] - AAA < BOARD_LEFT || - currentMoveString[2] - AAA < BOARD_LEFT ) - return ImpossibleMove; - - piece = boards[yyboardindex] - [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)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! - currentMoveString[1] - ONE, - currentMoveString[0] - AAA, - currentMoveString[3] - ONE, - currentMoveString[2] - AAA, - currentMoveString[4]); - - if (currentMoveString[4] == NULLCHAR && - (result == WhitePromotionKnight || result == BlackPromotionKnight || - result == WhitePromotionQueen || result == BlackPromotionQueen)) { - currentMoveString[4] = PieceToChar(BlackQueen); - currentMoveString[5] = NULLCHAR; - } - - return (int) result; -} +{ + /* + * Fully-qualified algebraic move, possibly with promotion + */ + 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] == '/') skip1++; + + /* remove the [xX:-] */ + if ((yytext[3+skip1] == 'x') || (yytext[3+skip1] == 'X') || + (yytext[3+skip1] == '-') || (yytext[3+skip1] == ':')) skip2 = 1; + + currentMoveString[0] = yytext[1+skip1]; + currentMoveString[1] = yytext[2+skip1]; + currentMoveString[2] = yytext[3+skip1+skip2]; + currentMoveString[3] = yytext[4+skip1+skip2]; + currentMoveString[4] = NULLCHAR; + + 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 { + 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[1] - ONE < 0 || + currentMoveString[0] - AAA >= BOARD_RGHT || + currentMoveString[3] - ONE >= BOARD_HEIGHT || + currentMoveString[3] - ONE < 0 || + currentMoveString[2] - AAA >= BOARD_RGHT || + currentMoveString[0] - AAA < BOARD_LEFT || + currentMoveString[2] - AAA < BOARD_LEFT ) + return ImpossibleMove; + + piece = boards[yyboardindex] + [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)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + currentMoveString[1] - ONE, + currentMoveString[0] - AAA, + currentMoveString[3] - ONE, + currentMoveString[2] - AAA, + currentMoveString[4]); + + if (currentMoveString[4] == NULLCHAR && + (result == WhitePromotion || result == BlackPromotion)) { + if(gameInfo.variant == VariantCourier || gameInfo.variant == VariantShatranj) + currentMoveString[4] = PieceToChar(BlackFerz); + else if(gameInfo.variant == VariantGreat) + currentMoveString[4] = PieceToChar(BlackMan); + else if(gameInfo.variant == VariantShogi) + currentMoveString[4] = '+'; + else + currentMoveString[4] = PieceToChar(BlackQueen); + currentMoveString[5] = NULLCHAR; + } + + return (int) result; +} YY_BREAK case 2: YY_RULE_SETUP -#line 263 "parser.l" -{ - /* - * Simple algebraic move, possibly with promotion - * [HGM] Engine moves are received in this format, with lower-case promoChar! - */ - int skip = 0; - ChessMove result; - - if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ - - /* remove the [xX:-] */ - if ((yytext[2] == 'x') || (yytext[2] == 'X') || - (yytext[2] == '-') || (yytext[2] == ':')) skip = 1; - - currentMoveString[0] = yytext[0]; - currentMoveString[1] = yytext[1]; - currentMoveString[2] = yytext[2+skip]; - currentMoveString[3] = yytext[3+skip]; - currentMoveString[4] = NULLCHAR; - - if (yyleng-skip > 4) { char c; - if (yytext[yyleng-1] == ')') { - c = currentMoveString[4] = ToLower(yytext[yyleng-2]); - } else { - 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[1] - ONE < 0 || - currentMoveString[0] - AAA >= BOARD_RGHT || - currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[3] - ONE < 0 || - currentMoveString[2] - AAA >= BOARD_RGHT || - currentMoveString[0] - AAA < BOARD_LEFT || - currentMoveString[2] - AAA < BOARD_LEFT ) - return ImpossibleMove; - - result = LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! - currentMoveString[1] - ONE, - currentMoveString[0] - AAA, - currentMoveString[3] - ONE, - currentMoveString[2] - AAA, - currentMoveString[4]); - +#line 269 "parser.l" +{ + /* + * Simple algebraic move, possibly with promotion + * [HGM] Engine moves are received in this format, with lower-case promoChar! + */ + int skip = 0; + ChessMove result; + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + + /* remove the [xX:-] */ + if ((yytext[2] == 'x') || (yytext[2] == 'X') || + (yytext[2] == '-') || (yytext[2] == ':')) skip = 1; + + currentMoveString[0] = yytext[0]; + currentMoveString[1] = yytext[1]; + currentMoveString[2] = yytext[2+skip]; + currentMoveString[3] = yytext[3+skip]; + currentMoveString[4] = NULLCHAR; + + if (yyleng-skip > 4) { char c; + if (yytext[yyleng-1] == ')') { + c = currentMoveString[4] = ToLower(yytext[yyleng-2]); + } else { + 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[1] - ONE < 0 || + currentMoveString[0] - AAA >= BOARD_RGHT || + currentMoveString[3] - ONE >= BOARD_HEIGHT || + currentMoveString[3] - ONE < 0 || + currentMoveString[2] - AAA >= BOARD_RGHT || + currentMoveString[0] - AAA < BOARD_LEFT || + currentMoveString[2] - AAA < BOARD_LEFT ) + return ImpossibleMove; + + result = LegalityTest(boards[yyboardindex], + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + currentMoveString[1] - ONE, + currentMoveString[0] - AAA, + currentMoveString[3] - ONE, + currentMoveString[2] - AAA, + currentMoveString[4]); + if (currentMoveString[4] == NULLCHAR) { - if(result == WhitePromotionKnight || result == BlackPromotionKnight || - result == WhitePromotionQueen || result == BlackPromotionQueen) { + if(result == WhitePromotion || result == BlackPromotion) { if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) currentMoveString[4] = PieceToChar(BlackFerz); else if(gameInfo.variant == VariantGreat) currentMoveString[4] = PieceToChar(BlackMan); + else if(gameInfo.variant == VariantShogi) + currentMoveString[4] = '+'; // Queen might not be defined in mini variants! else currentMoveString[4] = PieceToChar(BlackQueen); currentMoveString[5] = NULLCHAR; } } else if(appData.testLegality && // strip off unnecessary and false promo characters - !(result == WhitePromotionQueen || result == BlackPromotionQueen || - result == WhiteNonPromotion || result == BlackNonPromotion)) currentMoveString[4] = NULLCHAR; + !(result == WhitePromotion || result == BlackPromotion || + result == WhiteNonPromotion || result == BlackNonPromotion)) currentMoveString[4] = NULLCHAR; return (int) result; } YY_BREAK case 3: YY_RULE_SETUP -#line 331 "parser.l" +#line 338 "parser.l" { /* * Simple algebraic move, in capitals @@ -2358,649 +2365,646 @@ YY_RULE_SETUP currentMoveString[2] - AAA, currentMoveString[4]); - if (currentMoveString[4] == NULLCHAR && - (result == WhitePromotionKnight || result == BlackPromotionKnight || - result == WhitePromotionQueen || result == BlackPromotionQueen)) { - if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) - currentMoveString[4] = PieceToChar(BlackFerz); - else if(gameInfo.variant == VariantGreat) - currentMoveString[4] = PieceToChar(BlackMan); - else - currentMoveString[4] = PieceToChar(BlackQueen); - currentMoveString[5] = NULLCHAR; - } else if(appData.testLegality && // strip off unnecessary and false promo characters - !(result == WhitePromotionQueen || result == BlackPromotionQueen || - result == WhiteNonPromotion || result == BlackNonPromotion)) currentMoveString[4] = NULLCHAR; - - return (int) result; -} + if (currentMoveString[4] == NULLCHAR && + (result == WhitePromotion || result == BlackPromotion)) { + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) + currentMoveString[4] = PieceToChar(BlackFerz); + else if(gameInfo.variant == VariantGreat) + currentMoveString[4] = PieceToChar(BlackMan); + else + currentMoveString[4] = PieceToChar(BlackQueen); + currentMoveString[5] = NULLCHAR; + } + + return (int) result; +} YY_BREAK case 4: YY_RULE_SETUP -#line 387 "parser.l" -{ - /* - * Pawn move, possibly with promotion - */ - DisambiguateClosure cl; - int skip = 0; char c; - - if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ - - /* remove the =() */ - 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] - AAA; - cl.rtIn = yytext[1] - ONE; - cl.ftIn = yytext[0] - AAA; - c = cl.promoCharIn = ToLower(yytext[2+skip]); - - /* [HGM] do not allow values beyond board size */ - if(cl.rtIn >= BOARD_HEIGHT || - cl.rtIn < 0 || - cl.ffIn >= BOARD_RGHT || - cl.ftIn < BOARD_LEFT ) - return ImpossibleMove; - - if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare) - return IllegalMove; - - - Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); - - currentMoveString[0] = cl.ff + AAA; - currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + AAA; - currentMoveString[3] = cl.rt + ONE; - currentMoveString[4] = cl.promoChar; - currentMoveString[5] = NULLCHAR; - - return (int) cl.kind; -} +#line 391 "parser.l" +{ + /* + * Pawn move, possibly with promotion + */ + DisambiguateClosure cl; + int skip = 0; char c; + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + + /* remove the =() */ + 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] - AAA; + cl.rtIn = yytext[1] - ONE; + cl.ftIn = yytext[0] - AAA; + c = cl.promoCharIn = ToLower(yytext[2+skip]); + + /* [HGM] do not allow values beyond board size */ + if(cl.rtIn >= BOARD_HEIGHT || + cl.rtIn < 0 || + cl.ffIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) + return ImpossibleMove; + + if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare) + return IllegalMove; + + + Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); + + currentMoveString[0] = cl.ff + AAA; + currentMoveString[1] = cl.rf + ONE; + currentMoveString[2] = cl.ft + AAA; + currentMoveString[3] = cl.rt + ONE; + currentMoveString[4] = cl.promoChar; + currentMoveString[5] = NULLCHAR; + + return (int) cl.kind; +} YY_BREAK case 5: YY_RULE_SETUP -#line 431 "parser.l" -{ - /* - * Pawn capture, possibly with promotion, possibly ambiguous - */ - DisambiguateClosure cl; - int skip1 = 0, skip2 = 0; char c; - - if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ - - /* remove trailing ep or e.p. (nonstandard PGN) */ - if (yytext[yyleng-1] == 'p') { - yyleng -= 2; - yytext[yyleng] = NULLCHAR; - } else if (yytext[yyleng-1] == '.') { - yyleng -= 4; - yytext[yyleng] = NULLCHAR; - } - - /* remove the [xX:-] and =() */ - if ((yytext[1] == 'x') || (yytext[1] == 'X') - || (yytext[1] == ':') || (yytext[1] == '-')) skip1 = 1; - 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] - AAA; - cl.rtIn = -1; - 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_RGHT || - cl.ffIn < BOARD_LEFT || - cl.ftIn >= BOARD_RGHT || - cl.ftIn < BOARD_LEFT ) - return ImpossibleMove; - - if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare) - return IllegalMove; - - Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); - - currentMoveString[0] = cl.ff + AAA; - currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + AAA; - currentMoveString[3] = cl.rt + ONE; - currentMoveString[4] = cl.promoChar; - currentMoveString[5] = NULLCHAR; - - return (int) cl.kind; -} +#line 435 "parser.l" +{ + /* + * Pawn capture, possibly with promotion, possibly ambiguous + */ + DisambiguateClosure cl; + int skip1 = 0, skip2 = 0; char c; + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + + /* remove trailing ep or e.p. (nonstandard PGN) */ + if (yytext[yyleng-1] == 'p') { + yyleng -= 2; + yytext[yyleng] = NULLCHAR; + } else if (yytext[yyleng-1] == '.') { + yyleng -= 4; + yytext[yyleng] = NULLCHAR; + } + + /* remove the [xX:-] and =() */ + if ((yytext[1] == 'x') || (yytext[1] == 'X') + || (yytext[1] == ':') || (yytext[1] == '-')) skip1 = 1; + 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] - AAA; + cl.rtIn = -1; + 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_RGHT || + cl.ffIn < BOARD_LEFT || + cl.ftIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) + return ImpossibleMove; + + if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare) + return IllegalMove; + + Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); + + currentMoveString[0] = cl.ff + AAA; + currentMoveString[1] = cl.rf + ONE; + currentMoveString[2] = cl.ft + AAA; + currentMoveString[3] = cl.rt + ONE; + currentMoveString[4] = cl.promoChar; + currentMoveString[5] = NULLCHAR; + + return (int) cl.kind; +} YY_BREAK case 6: YY_RULE_SETUP -#line 484 "parser.l" -{ - /* - * unambiguously abbreviated Pawn capture, possibly with promotion - */ - int skip = 0; - ChessMove result; char c; - - if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ - - /* remove trailing ep or e.p. (nonstandard PGN) */ - if (yytext[yyleng-1] == 'p') { - yyleng -= 2; - yytext[yyleng] = NULLCHAR; - } else if (yytext[yyleng-1] == '.') { - yyleng -= 4; - yytext[yyleng] = NULLCHAR; - } - - /* remove the [xX:-] */ - if ((yytext[1] == 'x') || (yytext[1] == 'X') - || (yytext[1] == ':') || (yytext[1] == '-')) skip = 1; - - currentMoveString[0] = yytext[0]; - currentMoveString[2] = yytext[1+skip]; - currentMoveString[3] = yytext[2+skip]; - - /* [HGM] do not allow values beyond board size */ - if(currentMoveString[0] - AAA >= BOARD_RGHT || - currentMoveString[3] - ONE >= BOARD_HEIGHT || - currentMoveString[3] - ONE < 0 || - currentMoveString[2] - AAA >= BOARD_RGHT || - currentMoveString[0] - AAA < BOARD_LEFT || - currentMoveString[2] - AAA < BOARD_LEFT ) - return ImpossibleMove; - - if (gameInfo.variant == VariantXiangqi && /* [HGM] In Xiangqi rank stays same */ - currentMoveString[0] != currentMoveString[2] ) { - 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] == ')') - c = currentMoveString[4] = ToLower(yytext[yyleng-2]); - else - 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)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! - currentMoveString[1] - ONE, - currentMoveString[0] - AAA, - currentMoveString[3] - ONE, - currentMoveString[2] - AAA, - currentMoveString[4]); - - if (currentMoveString[4] == NULLCHAR && - (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 || gameInfo.variant == VariantMakruk) - currentMoveString[4] = PieceToChar(BlackFerz); - if(gameInfo.variant == VariantGreat) - currentMoveString[4] = PieceToChar(BlackMan); - currentMoveString[5] = NULLCHAR; - } - - if (result != IllegalMove) return (int) result; - - /* Special case: improperly written en passant capture */ - if (WhiteOnMove(yyboardindex)) { - if (currentMoveString[3] == '5') { - currentMoveString[1] = '5'; - currentMoveString[3] = '6'; - } else { - return (int) IllegalMove; - } - } else { - if (currentMoveString[3] == '4') { - currentMoveString[1] = '4'; - currentMoveString[3] = '3'; - } else { - return (int) IllegalMove; - } - } - - result = LegalityTest(boards[yyboardindex], - PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! - currentMoveString[1] - ONE, - currentMoveString[0] - AAA, - currentMoveString[3] - ONE, - currentMoveString[2] - AAA, - currentMoveString[4]); - - if (result == WhiteCapturesEnPassant || result == BlackCapturesEnPassant) - return (int) result; - else - return (int) IllegalMove; -} +#line 488 "parser.l" +{ + /* + * unambiguously abbreviated Pawn capture, possibly with promotion + */ + int skip = 0; + ChessMove result; char c; + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + + /* remove trailing ep or e.p. (nonstandard PGN) */ + if (yytext[yyleng-1] == 'p') { + yyleng -= 2; + yytext[yyleng] = NULLCHAR; + } else if (yytext[yyleng-1] == '.') { + yyleng -= 4; + yytext[yyleng] = NULLCHAR; + } + + /* remove the [xX:-] */ + if ((yytext[1] == 'x') || (yytext[1] == 'X') + || (yytext[1] == ':') || (yytext[1] == '-')) skip = 1; + + currentMoveString[0] = yytext[0]; + currentMoveString[2] = yytext[1+skip]; + currentMoveString[3] = yytext[2+skip]; + + /* [HGM] do not allow values beyond board size */ + if(currentMoveString[0] - AAA >= BOARD_RGHT || + currentMoveString[3] - ONE >= BOARD_HEIGHT || + currentMoveString[3] - ONE < 0 || + currentMoveString[2] - AAA >= BOARD_RGHT || + currentMoveString[0] - AAA < BOARD_LEFT || + currentMoveString[2] - AAA < BOARD_LEFT ) + return ImpossibleMove; + + if (gameInfo.variant == VariantXiangqi && /* [HGM] In Xiangqi rank stays same */ + currentMoveString[0] != currentMoveString[2] ) { + 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] == ')') + c = currentMoveString[4] = ToLower(yytext[yyleng-2]); + else + 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)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + currentMoveString[1] - ONE, + currentMoveString[0] - AAA, + currentMoveString[3] - ONE, + currentMoveString[2] - AAA, + currentMoveString[4]); + + if (currentMoveString[4] == NULLCHAR && + (result == WhitePromotion || result == BlackPromotion)) { + currentMoveString[4] = PieceToChar(BlackQueen); + // [HGM] shatranj: take care of variants without Queen + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) + currentMoveString[4] = PieceToChar(BlackFerz); + if(gameInfo.variant == VariantGreat) + currentMoveString[4] = PieceToChar(BlackMan); + currentMoveString[5] = NULLCHAR; + } + + if (result != IllegalMove) return (int) result; + + /* Special case: improperly written en passant capture */ + if (WhiteOnMove(yyboardindex)) { + if (currentMoveString[3] == '5') { + currentMoveString[1] = '5'; + currentMoveString[3] = '6'; + } else { + return (int) IllegalMove; + } + } else { + if (currentMoveString[3] == '4') { + currentMoveString[1] = '4'; + currentMoveString[3] = '3'; + } else { + return (int) IllegalMove; + } + } + + result = LegalityTest(boards[yyboardindex], + PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.! + currentMoveString[1] - ONE, + currentMoveString[0] - AAA, + currentMoveString[3] - ONE, + currentMoveString[2] - AAA, + currentMoveString[4]); + + if (result == WhiteCapturesEnPassant || result == BlackCapturesEnPassant) + return (int) result; + else + return (int) IllegalMove; +} YY_BREAK case 7: YY_RULE_SETUP -#line 599 "parser.l" -{ - /* - * piece move, possibly ambiguous - */ - DisambiguateClosure cl; - 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+skip] == 'x') || (yytext[1+skip] == 'X') - || (yytext[1+skip] == ':') || (yytext[1+skip] == '-')) skip++; - - if (WhiteOnMove(yyboardindex)) { - cl.pieceIn = CharToPiece(ToUpper(yytext[skip2])); - } else { - 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] - 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.rtIn < 0 || - cl.ftIn >= BOARD_RGHT || - cl.ftIn < BOARD_LEFT ) - return ImpossibleMove; - - Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); - - currentMoveString[0] = cl.ff + AAA; - currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + AAA; - currentMoveString[3] = cl.rt + ONE; - currentMoveString[4] = cl.promoChar; - currentMoveString[5] = NULLCHAR; - - return (int) cl.kind; -} +#line 602 "parser.l" +{ + /* + * piece move, possibly ambiguous + */ + DisambiguateClosure cl; + 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+skip] == 'x') || (yytext[1+skip] == 'X') + || (yytext[1+skip] == ':') || (yytext[1+skip] == '-')) skip++; + + if (WhiteOnMove(yyboardindex)) { + cl.pieceIn = CharToPiece(ToUpper(yytext[skip2])); + } else { + 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] - 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.rtIn < 0 || + cl.ftIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) + return ImpossibleMove; + + Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); + + currentMoveString[0] = cl.ff + AAA; + currentMoveString[1] = cl.rf + ONE; + currentMoveString[2] = cl.ft + AAA; + currentMoveString[3] = cl.rt + ONE; + currentMoveString[4] = cl.promoChar; + currentMoveString[5] = NULLCHAR; + + return (int) cl.kind; +} YY_BREAK case 8: YY_RULE_SETUP -#line 655 "parser.l" -{ - /* - * piece move with rank or file disambiguator - */ - DisambiguateClosure cl; - 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+skip] == 'x') || (yytext[2+skip] == 'X') - || (yytext[2+skip] == ':') || (yytext[2+skip] == '-')) skip++; - - if (WhiteOnMove(yyboardindex)) { - cl.pieceIn = CharToPiece(ToUpper(yytext[skip2])); - } else { - cl.pieceIn = CharToPiece(ToLower(yytext[skip2])); - } - if(promoted) cl.pieceIn = (ChessSquare) (PROMOTED cl.pieceIn); - - if (isalpha(yytext[1+skip2])) { - cl.rfIn = -1; - cl.ffIn = yytext[1+skip2] - AAA; - - if(cl.ffIn >= BOARD_RGHT || - cl.ffIn < BOARD_LEFT ) return 0; - } else { - 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] - 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.rtIn < 0 || - cl.ftIn >= BOARD_RGHT || - cl.ftIn < BOARD_LEFT ) - return ImpossibleMove; - - Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); - - currentMoveString[0] = cl.ff + AAA; - currentMoveString[1] = cl.rf + ONE; - currentMoveString[2] = cl.ft + AAA; - currentMoveString[3] = cl.rt + ONE; - currentMoveString[4] = cl.promoChar; - currentMoveString[5] = NULLCHAR; - - return (int) cl.kind; -} +#line 658 "parser.l" +{ + /* + * piece move with rank or file disambiguator + */ + DisambiguateClosure cl; + 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+skip] == 'x') || (yytext[2+skip] == 'X') + || (yytext[2+skip] == ':') || (yytext[2+skip] == '-')) skip++; + + if (WhiteOnMove(yyboardindex)) { + cl.pieceIn = CharToPiece(ToUpper(yytext[skip2])); + } else { + cl.pieceIn = CharToPiece(ToLower(yytext[skip2])); + } + if(promoted) cl.pieceIn = (ChessSquare) (PROMOTED cl.pieceIn); + + if (isalpha(yytext[1+skip2])) { + cl.rfIn = -1; + cl.ffIn = yytext[1+skip2] - AAA; + + if(cl.ffIn >= BOARD_RGHT || + cl.ffIn < BOARD_LEFT ) return 0; + } else { + 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] - 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.rtIn < 0 || + cl.ftIn >= BOARD_RGHT || + cl.ftIn < BOARD_LEFT ) + return ImpossibleMove; + + Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl); + + currentMoveString[0] = cl.ff + AAA; + currentMoveString[1] = cl.rf + ONE; + currentMoveString[2] = cl.ft + AAA; + currentMoveString[3] = cl.rt + ONE; + currentMoveString[4] = cl.promoChar; + currentMoveString[5] = NULLCHAR; + + return (int) cl.kind; +} YY_BREAK case 9: YY_RULE_SETUP -#line 715 "parser.l" -{ - int rf, ff, rt, ft; - - if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ - - /* [HGM] all squares referenced to board edges in stead of absolute */ - if (WhiteOnMove(yyboardindex)) { - if (boards[yyboardindex][0][(BOARD_WIDTH-1)>>1] == WhiteKing) { - /* ICS wild castling */ - rf = 0; - ff = (BOARD_WIDTH-1)>>1; - rt = 0; - ft = BOARD_RGHT-3; - } else { - rf = 0; - ff = BOARD_WIDTH>>1; - rt = 0; - ft = BOARD_LEFT+2; - } - } else{ - 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_RGHT-3; - } else { - rf = BOARD_HEIGHT-1; - ff = BOARD_WIDTH>>1; - rt = BOARD_HEIGHT-1; - ft = BOARD_LEFT+2; - } - } +#line 718 "parser.l" +{ + int rf, ff, rt, ft; + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + + /* [HGM] all squares referenced to board edges in stead of absolute */ + if (WhiteOnMove(yyboardindex)) { + if (boards[yyboardindex][0][(BOARD_WIDTH-1)>>1] == WhiteKing) { + /* ICS wild castling */ + rf = 0; + ff = (BOARD_WIDTH-1)>>1; + rt = 0; + ft = BOARD_RGHT-3; + } else { + rf = 0; + ff = BOARD_WIDTH>>1; + rt = 0; + ft = BOARD_LEFT+2; + } + } else{ + 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_RGHT-3; + } else { + rf = BOARD_HEIGHT-1; + ff = BOARD_WIDTH>>1; + rt = BOARD_HEIGHT-1; + ft = BOARD_LEFT+2; + } + } if(PosFlags(0) & F_FRC_TYPE_CASTLING) { - if (WhiteOnMove(yyboardindex)) { - ff = initialRights[2]; - ft = initialRights[1]; - } else { - ff = initialRights[5]; - ft = initialRights[4]; - } - if (appData.debugMode) - { - 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)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.! - rf, ff, rt, ft, NULLCHAR); -} + + if (WhiteOnMove(yyboardindex)) { + ff = initialRights[2]; + ft = initialRights[1]; + } else { + ff = initialRights[5]; + ft = initialRights[4]; + } + if (appData.debugMode) + { + 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)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.! + rf, ff, rt, ft, NULLCHAR); +} YY_BREAK case 10: YY_RULE_SETUP -#line 771 "parser.l" -{ - int rf, ff, rt, ft; - - if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ - - if (WhiteOnMove(yyboardindex)) { - if (boards[yyboardindex][0][(BOARD_WIDTH-1)>>1] == WhiteKing) { - /* ICS wild castling */ - rf = 0; - ff = (BOARD_WIDTH-1)>>1; - rt = 0; - ft = BOARD_LEFT+1; - } else { - rf = 0; - ff = BOARD_WIDTH>>1; - rt = 0; - ft = BOARD_RGHT-2; - } - } else { - 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_LEFT+1; - } else { - rf = BOARD_HEIGHT-1; - ff = BOARD_WIDTH>>1; - rt = BOARD_HEIGHT-1; - ft = BOARD_RGHT-2; - } - } +#line 775 "parser.l" +{ + int rf, ff, rt, ft; + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + + if (WhiteOnMove(yyboardindex)) { + if (boards[yyboardindex][0][(BOARD_WIDTH-1)>>1] == WhiteKing) { + /* ICS wild castling */ + rf = 0; + ff = (BOARD_WIDTH-1)>>1; + rt = 0; + ft = BOARD_LEFT+1; + } else { + rf = 0; + ff = BOARD_WIDTH>>1; + rt = 0; + ft = BOARD_RGHT-2; + } + } else { + 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_LEFT+1; + } else { + rf = BOARD_HEIGHT-1; + ff = BOARD_WIDTH>>1; + rt = BOARD_HEIGHT-1; + ft = BOARD_RGHT-2; + } + } if(PosFlags(0) & F_FRC_TYPE_CASTLING) { - 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)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.! - rf, ff, rt, ft, NULLCHAR); -} + 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)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.! + rf, ff, rt, ft, NULLCHAR); +} YY_BREAK case 11: YY_RULE_SETUP -#line 826 "parser.l" -{ - /* Bughouse piece drop. */ - 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[3] - ONE >= BOARD_HEIGHT || - currentMoveString[2] - AAA >= BOARD_WIDTH ) - return ImpossibleMove; - - if (WhiteOnMove(yyboardindex)) { - currentMoveString[0] = ToUpper(yytext[0]); - } else { - currentMoveString[0] = ToLower(yytext[0]); - } +#line 830 "parser.l" +{ + /* Bughouse piece drop. */ + 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[3] - ONE >= BOARD_HEIGHT || + currentMoveString[2] - AAA >= BOARD_WIDTH ) + return ImpossibleMove; + + if (WhiteOnMove(yyboardindex)) { + currentMoveString[0] = ToUpper(yytext[0]); + } else { + currentMoveString[0] = ToLower(yytext[0]); + } return LegalityTest(boards[yyboardindex], PosFlags(yyboardindex), DROP_RANK, // [HGM] does drops now too CharToPiece(currentMoveString[0]), currentMoveString[3] - ONE, currentMoveString[2] - AAA, NULLCHAR); -} +} YY_BREAK case 12: YY_RULE_SETUP -#line 850 "parser.l" -{ - if (WhiteOnMove(yyboardindex)) - return (int) BlackWins; - else - return (int) WhiteWins; -} +#line 854 "parser.l" +{ + if (WhiteOnMove(yyboardindex)) + return (int) BlackWins; + else + return (int) WhiteWins; +} YY_BREAK case 13: YY_RULE_SETUP -#line 857 "parser.l" -{ - return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins); -} +#line 861 "parser.l" +{ + return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins); +} YY_BREAK case 14: YY_RULE_SETUP -#line 861 "parser.l" -{ - return (int) GameUnfinished; -} +#line 865 "parser.l" +{ + return (int) GameUnfinished; +} YY_BREAK case 15: YY_RULE_SETUP -#line 865 "parser.l" -{ - return (int) GameIsDrawn; -} +#line 869 "parser.l" +{ + return (int) GameIsDrawn; +} YY_BREAK case 16: YY_RULE_SETUP -#line 869 "parser.l" -{ - return (int) GameIsDrawn; -} +#line 873 "parser.l" +{ + return (int) GameIsDrawn; +} YY_BREAK case 17: YY_RULE_SETUP -#line 873 "parser.l" -{ - if (WhiteOnMove(yyboardindex)) - return (int) BlackWins; - else - return (int) WhiteWins; -} +#line 877 "parser.l" +{ + if (WhiteOnMove(yyboardindex)) + return (int) BlackWins; + else + return (int) WhiteWins; +} YY_BREAK case 18: YY_RULE_SETUP -#line 880 "parser.l" -{ - if (WhiteOnMove(yyboardindex)) - return (int) BlackWins; - else - return (int) WhiteWins; -} +#line 884 "parser.l" +{ + if (WhiteOnMove(yyboardindex)) + return (int) BlackWins; + else + return (int) WhiteWins; +} YY_BREAK case 19: YY_RULE_SETUP -#line 887 "parser.l" -{ - return (int) GameIsDrawn; -} +#line 891 "parser.l" +{ + return (int) GameIsDrawn; +} YY_BREAK case 20: YY_RULE_SETUP -#line 891 "parser.l" -{ - return (int) GameIsDrawn; -} +#line 895 "parser.l" +{ + return (int) GameIsDrawn; +} YY_BREAK case 21: YY_RULE_SETUP -#line 895 "parser.l" -{ - return (int) (ToUpper(yytext[0]) == 'W' ? WhiteWins : BlackWins); -} +#line 899 "parser.l" +{ + return (int) (ToUpper(yytext[0]) == 'W' ? WhiteWins : BlackWins); +} YY_BREAK case 22: YY_RULE_SETUP -#line 899 "parser.l" -{ - return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins); -} +#line 903 "parser.l" +{ + return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins); +} YY_BREAK case 23: YY_RULE_SETUP -#line 903 "parser.l" -{ - return (int) WhiteWins; -} +#line 907 "parser.l" +{ + return (int) WhiteWins; +} YY_BREAK case 24: YY_RULE_SETUP -#line 907 "parser.l" -{ - return (int) BlackWins; -} +#line 911 "parser.l" +{ + return (int) BlackWins; +} YY_BREAK case 25: YY_RULE_SETUP -#line 911 "parser.l" -{ - return (int) GameIsDrawn; -} +#line 915 "parser.l" +{ + return (int) GameIsDrawn; +} YY_BREAK case 26: YY_RULE_SETUP -#line 915 "parser.l" -{ - return (int) GameUnfinished; -} +#line 919 "parser.l" +{ + return (int) GameUnfinished; +} YY_BREAK case 27: /* rule 27 can match eol */ YY_RULE_SETUP -#line 919 "parser.l" -{ - /* move numbers */ - if ((yyleng == 1) && (yytext[0] == '1')) - return (int) MoveNumberOne; -} +#line 923 "parser.l" +{ + /* move numbers */ + if ((yyleng == 1) && (yytext[0] == '1')) + return (int) MoveNumberOne; +} YY_BREAK case 28: YY_RULE_SETUP -#line 925 "parser.l" -{ - /* elapsed time indication, e.g. (0:12) or {10:21.071} */ - return (int) ElapsedTime; -} +#line 929 "parser.l" +{ + /* elapsed time indication, e.g. (0:12) or {10:21.071} */ + return (int) ElapsedTime; +} YY_BREAK case 29: /* rule 29 can match eol */ YY_RULE_SETUP -#line 930 "parser.l" -{ - /* position diagram enclosed in [-- --] */ - return (int) PositionDiagram; -} +#line 934 "parser.l" +{ + /* position diagram enclosed in [-- --] */ + return (int) PositionDiagram; +} YY_BREAK case 30: /* rule 30 can match eol */ @@ -3008,26 +3012,26 @@ case 30: (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 935 "parser.l" -{ - /* position diagram enclosed in {-- --} */ - return (int) PositionDiagram; -} +#line 939 "parser.l" +{ + /* position diagram enclosed in {-- --} */ + return (int) PositionDiagram; +} YY_BREAK case 31: /* rule 31 can match eol */ YY_RULE_SETUP -#line 940 "parser.l" -{ - return (int) PGNTag; -} +#line 944 "parser.l" +{ + return (int) PGNTag; +} YY_BREAK case 32: YY_RULE_SETUP -#line 944 "parser.l" -{ - return (int) GNUChessGame; -} +#line 948 "parser.l" +{ + return (int) GNUChessGame; +} YY_BREAK case 33: /* rule 33 can match eol */ @@ -3035,89 +3039,89 @@ case 33: (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 948 "parser.l" -{ - return (int) XBoardGame; -} +#line 952 "parser.l" +{ + return (int) XBoardGame; +} YY_BREAK case 34: YY_RULE_SETUP -#line 952 "parser.l" -{ /* numeric annotation glyph */ - return (int) NAG; -} +#line 956 "parser.l" +{ /* numeric annotation glyph */ + return (int) NAG; +} YY_BREAK case 35: /* rule 35 can match eol */ YY_RULE_SETUP -#line 956 "parser.l" -{ /* anything in {} */ - return (int) Comment; -} +#line 960 "parser.l" +{ /* anything in {} */ + return (int) Comment; +} YY_BREAK case 36: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 960 "parser.l" -{ /* ; to end of line */ - return (int) Comment; -} +#line 964 "parser.l" +{ /* ; to end of line */ + return (int) Comment; +} YY_BREAK case 37: /* rule 37 can match eol */ YY_RULE_SETUP -#line 964 "parser.l" -{ /* anything in [] */ - return (int) Comment; -} +#line 968 "parser.l" +{ /* anything in [] */ + return (int) Comment; +} YY_BREAK case 38: /* rule 38 can match eol */ YY_RULE_SETUP -#line 968 "parser.l" -{ /* very nested () */ - return (int) Comment; -} +#line 972 "parser.l" +{ /* very nested () */ + return (int) Comment; +} YY_BREAK case 39: /* rule 39 can match eol */ YY_RULE_SETUP -#line 972 "parser.l" -{ /* >=2 chars in () */ - return (int) Comment; -} +#line 976 "parser.l" +{ /* >=2 chars in () */ + return (int) Comment; +} YY_BREAK case 40: /* rule 40 can match eol */ YY_RULE_SETUP -#line 976 "parser.l" -{ - /* Skip mail headers */ -} +#line 980 "parser.l" +{ + /* Skip mail headers */ +} YY_BREAK case 41: YY_RULE_SETUP -#line 980 "parser.l" -{ - /* Skip random words */ -} +#line 984 "parser.l" +{ + /* Skip random words */ +} YY_BREAK case 42: /* rule 42 can match eol */ YY_RULE_SETUP -#line 984 "parser.l" -{ - /* Skip everything else */ -} +#line 988 "parser.l" +{ + /* Skip everything else */ +} YY_BREAK case 43: YY_RULE_SETUP -#line 988 "parser.l" +#line 992 "parser.l" ECHO; YY_BREAK -#line 3121 "parser.c" +#line 3125 "parser.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -4092,197 +4096,197 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 988 "parser.l" +#line 992 "parser.l" + - - -static char *StringToLex; - -#ifndef FLEX_SCANNER -static FILE *lexFP; - -static int input() -{ - int ret; - - if (StringToLex != NULL) { - ret = *StringToLex; - if (ret == NULLCHAR) - ret = EOF; - else - StringToLex++; - } else if (unputCount > 0) { - ret = unputBuffer[--unputCount]; - } else { - ret = fgetc(lexFP); - } - - if (ret == EOF) - return 0; - else - return ret; -} - -/* - * Return offset of next pattern within current file - */ -int yyoffset() -{ - int offset = ftell(lexFP) - unputCount; - - if (offset < 0) { - offset = 0; - } - return(offset); -} - -static void output(ch) - int ch; -{ - if(appData.debugMode) fprintf(debugFP, "PARSER BUG: unmatched character '%c' (0%o)\n", - ch, ch); -} - -static void unput(ch) - int ch; -{ - if (ch == 0) return; - if (StringToLex != NULL) { - StringToLex--; - } else { - if (unputCount >= UNPUT_BUF_SIZE) - if(appData.debugMode) fprintf(debugFP, "PARSER BUG: unput buffer overflow '%c' (0%o)\n", - ch, ch); - unputBuffer[unputCount++] = ch; - } -} - -/* Get ready to lex from a new file. Kludge below sticks - an artificial newline at the front of the file, which the - above grammar ignores, but which makes ^ at start of pattern - match at the real start of the file. -*/ -void yynewfile(f) - FILE *f; -{ - lexFP = f; - StringToLex = NULL; - unputCount = 0; - unput('\n'); /* kludge */ -} - -/* Get ready to lex from a string. ^ at start of pattern WON'T - match at the start of the string! -*/ -void yynewstr(s) - char *s; -{ - lexFP = NULL; - StringToLex = s; - unputCount = 0; -} -#endif /*!FLEX_SCANNER*/ - -#ifdef FLEX_SCANNER -void my_yy_input(buf, result, max_size) - char *buf; - int *result; - int max_size; -{ - int count; - - if (StringToLex != NULL) { - count = 0; - while (*StringToLex != NULLCHAR) { - *buf++ = *StringToLex++; - count++; - } - *result = count; - return; - } else { - count = fread(buf, 1, max_size, yyin); - if (count == 0) { - *result = YY_NULL; - } else { - *result = count; - } - return; - } -} - -static YY_BUFFER_STATE my_file_buffer = NULL; - -/* - Return offset of next pattern in the current file. -*/ -int yyoffset() -{ - int pos = yy_c_buf_p - YY_CURRENT_BUFFER->yy_ch_buf; - - return(ftell(YY_CURRENT_BUFFER->yy_input_file) - - yy_n_chars + pos); -} - - -void yynewstr(s) - char *s; -{ - if (my_file_buffer != NULL) - yy_delete_buffer(my_file_buffer); - StringToLex = s; - my_file_buffer = yy_create_buffer(stdin,YY_BUF_SIZE); - yy_switch_to_buffer(my_file_buffer); -} - -void yynewfile(f) - FILE *f; -{ - if (my_file_buffer != NULL) - yy_delete_buffer(my_file_buffer); - StringToLex = NULL; - my_file_buffer = yy_create_buffer(f,YY_BUF_SIZE); - yy_switch_to_buffer(my_file_buffer); -} -#endif /*FLEX_SCANNER*/ - -int yywrap() -{ - return TRUE; -} - -/* Parse a move from the given string s */ -/* ^ at start of pattern WON'T work here unless using flex */ -ChessMove yylexstr(boardIndex, s, text, len) - int boardIndex, len; - char *s, *text; + +static char *StringToLex; + +#ifndef FLEX_SCANNER +static FILE *lexFP; + +static int input() +{ + int ret; + + if (StringToLex != NULL) { + ret = *StringToLex; + if (ret == NULLCHAR) + ret = EOF; + else + StringToLex++; + } else if (unputCount > 0) { + ret = unputBuffer[--unputCount]; + } else { + ret = fgetc(lexFP); + } + + if (ret == EOF) + return 0; + else + return ret; +} + +/* + * Return offset of next pattern within current file + */ +int yyoffset() +{ + int offset = ftell(lexFP) - unputCount; + + if (offset < 0) { + offset = 0; + } + return(offset); +} + +static void output(ch) + int ch; { - ChessMove ret; - char *oldStringToLex; -#ifdef FLEX_SCANNER - YY_BUFFER_STATE buffer, oldBuffer; -#endif - - yyboardindex = boardIndex; - oldStringToLex = StringToLex; - StringToLex = s; -#ifdef FLEX_SCANNER - buffer = yy_create_buffer(stdin,YY_BUF_SIZE); - oldBuffer = YY_CURRENT_BUFFER; - yy_switch_to_buffer(buffer); -#endif /*FLEX_SCANNER*/ - + if(appData.debugMode) fprintf(debugFP, "PARSER BUG: unmatched character '%c' (0%o)\n", + ch, ch); +} + +static void unput(ch) + int ch; +{ + if (ch == 0) return; + if (StringToLex != NULL) { + StringToLex--; + } else { + if (unputCount >= UNPUT_BUF_SIZE) + if(appData.debugMode) fprintf(debugFP, "PARSER BUG: unput buffer overflow '%c' (0%o)\n", + ch, ch); + unputBuffer[unputCount++] = ch; + } +} + +/* Get ready to lex from a new file. Kludge below sticks + an artificial newline at the front of the file, which the + above grammar ignores, but which makes ^ at start of pattern + match at the real start of the file. +*/ +void yynewfile(f) + FILE *f; +{ + lexFP = f; + StringToLex = NULL; + unputCount = 0; + unput('\n'); /* kludge */ +} + +/* Get ready to lex from a string. ^ at start of pattern WON'T + match at the start of the string! +*/ +void yynewstr(s) + char *s; +{ + lexFP = NULL; + StringToLex = s; + unputCount = 0; +} +#endif /*!FLEX_SCANNER*/ + +#ifdef FLEX_SCANNER +void my_yy_input(buf, result, max_size) + char *buf; + int *result; + int max_size; +{ + int count; + + if (StringToLex != NULL) { + count = 0; + while (*StringToLex != NULLCHAR) { + *buf++ = *StringToLex++; + count++; + } + *result = count; + return; + } else { + count = fread(buf, 1, max_size, yyin); + if (count == 0) { + *result = YY_NULL; + } else { + *result = count; + } + return; + } +} + +static YY_BUFFER_STATE my_file_buffer = NULL; + +/* + Return offset of next pattern in the current file. +*/ +int yyoffset() +{ + int pos = yy_c_buf_p - YY_CURRENT_BUFFER->yy_ch_buf; + + return(ftell(YY_CURRENT_BUFFER->yy_input_file) - + yy_n_chars + pos); +} + + +void yynewstr(s) + char *s; +{ + if (my_file_buffer != NULL) + yy_delete_buffer(my_file_buffer); + StringToLex = s; + my_file_buffer = yy_create_buffer(stdin,YY_BUF_SIZE); + yy_switch_to_buffer(my_file_buffer); +} + +void yynewfile(f) + FILE *f; +{ + if (my_file_buffer != NULL) + yy_delete_buffer(my_file_buffer); + StringToLex = NULL; + my_file_buffer = yy_create_buffer(f,YY_BUF_SIZE); + yy_switch_to_buffer(my_file_buffer); +} +#endif /*FLEX_SCANNER*/ + +int yywrap() +{ + return TRUE; +} + +/* Parse a move from the given string s */ +/* ^ at start of pattern WON'T work here unless using flex */ +ChessMove yylexstr(boardIndex, s, text, len) + int boardIndex, len; + char *s, *text; +{ + ChessMove ret; + char *oldStringToLex; +#ifdef FLEX_SCANNER + YY_BUFFER_STATE buffer, oldBuffer; +#endif + + yyboardindex = boardIndex; + oldStringToLex = StringToLex; + StringToLex = s; +#ifdef FLEX_SCANNER + buffer = yy_create_buffer(stdin,YY_BUF_SIZE); + oldBuffer = YY_CURRENT_BUFFER; + yy_switch_to_buffer(buffer); +#endif /*FLEX_SCANNER*/ + ret = (ChessMove) yylex(); strncpy(text, yy_text, len-1); // [HGM] vari: yy_text is not available to caller after buffer switch ?!? - text[len-1] = NULLCHAR; - -#ifdef FLEX_SCANNER - if (oldBuffer != NULL) - yy_switch_to_buffer(oldBuffer); - yy_delete_buffer(buffer); -#endif /*FLEX_SCANNER*/ - StringToLex = oldStringToLex; - - return ret; -} + text[len-1] = NULLCHAR; + +#ifdef FLEX_SCANNER + if (oldBuffer != NULL) + yy_switch_to_buffer(oldBuffer); + yy_delete_buffer(buffer); +#endif /*FLEX_SCANNER*/ + StringToLex = oldStringToLex; + + return ret; +}