9 * parser.l -- lex parser of algebraic chess moves for XBoard
12 * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
13 * Enhancements Copyright 1992-95 Free Software Foundation, Inc.
15 * The following terms apply to Digital Equipment Corporation's copyright
17 * ------------------------------------------------------------------------
20 * Permission to use, copy, modify, and distribute this software and its
21 * documentation for any purpose and without fee is hereby granted,
22 * provided that the above copyright notice appear in all copies and that
23 * both that copyright notice and this permission notice appear in
24 * supporting documentation, and that the name of Digital not be
25 * used in advertising or publicity pertaining to distribution of the
26 * software without specific, written prior permission.
28 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
29 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
30 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
31 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
32 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
33 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
35 * ------------------------------------------------------------------------
37 * The following terms apply to the enhanced version of XBoard distributed
38 * by the Free Software Foundation:
39 * ------------------------------------------------------------------------
40 * This program is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License as published by
42 * the Free Software Foundation; either version 2 of the License, or
43 * (at your option) any later version.
45 * This program is distributed in the hope that it will be useful,
46 * but WITHOUT ANY WARRANTY; without even the implied warranty of
47 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 * GNU General Public License for more details.
50 * You should have received a copy of the GNU General Public License
51 * along with this program; if not, write to the Free Software
52 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
53 * ------------------------------------------------------------------------
56 /* This parser handles all forms of promotion.
57 * The parser resolves ambiguous moves by searching and check-testing.
58 * It also parses comments of the form [anything] or (anything).
63 #define NO_CONSTRAINT -1
66 #define UNPUT_BUF_SIZE YYLMAX
69 /* yytext is probably a char*, but could be a char[]. yy_text is set
70 in YY_DECL below, because if yytext is a char*, its value is not
73 #else /*!FLEX_SCANNER*/
74 /* yytext is definitely a char[], so yy_text can be set here, statically. */
75 char *yy_text = (char *) yytext;
80 /* use prototypes in function declarations */
84 #define YY_PROTO(proto) proto
86 #define YY_PROTO(proto) ()
90 #define YY_INPUT(buf, result, max_size) my_yy_input(buf, &result, max_size)
93 int _yylex YY_PROTO((void)); \
94 int yylex YY_PROTO((void)) \
96 int result = _yylex(); \
97 yy_text = (char *) yytext; \
100 int _yylex YY_PROTO((void))
108 /* The includes must be here, below the #undef input */
115 #else /* not STDC_HEADERS */
118 # else /* not HAVE_STRING_H */
119 # include <strings.h>
120 # endif /* not HAVE_STRING_H */
121 #endif /* not STDC_HEADERS */
127 #if defined(_amigados)
130 # include <fcntl.h> /* isatty() prototype */
131 # endif /* HAVE_FCNTL_H */
132 #endif /* defined(_amigados) */
136 #include "frontend.h"
140 extern int PosFlags P((int));
142 extern Board boards[MAX_MOVES];
144 int yyskipmoves = FALSE;
145 char currentMoveString[YYLMAX];
147 char unputBuffer[UNPUT_BUF_SIZE];
152 void my_yy_input P((char *buf, int *result, int max_size));
153 #else /*!FLEX_SCANNER*/
154 static int input P((void));
155 static void output P((int ch));
156 static void unput P((int ch));
157 int yylook P((void));
158 int yyback P((int *, int));
161 int yywrap P((void));
162 extern void CopyBoard P((Board to, Board from));
167 [RrBbNnQqKkPp][/]?[a-h][1-8][xX:-]?[a-h][1-8](=?\(?[RrBbNnQqKk]\)?)? {
169 * Fully-qualified algebraic move, possibly with promotion
171 int skip1 = 0, skip2 = 0;
175 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
178 if (yytext[1] == '/') skip1 = 1;
180 /* remove the [xX:-] */
181 if ((yytext[3+skip1] == 'x') || (yytext[3+skip1] == 'X') ||
182 (yytext[3+skip1] == '-') || (yytext[3+skip1] == ':')) skip2 = 1;
184 currentMoveString[0] = yytext[1+skip1];
185 currentMoveString[1] = yytext[2+skip1];
186 currentMoveString[2] = yytext[3+skip1+skip2];
187 currentMoveString[3] = yytext[4+skip1+skip2];
188 currentMoveString[4] = NULLCHAR;
190 if (yyleng-skip1-skip2 > 5) {
191 if (yytext[yyleng-1] == ')') {
192 currentMoveString[4] = ToLower(yytext[yyleng-2]);
194 currentMoveString[4] = ToLower(yytext[yyleng-1]);
196 currentMoveString[5] = NULLCHAR;
199 piece = boards[yyboardindex]
200 [currentMoveString[1] - '1'][currentMoveString[0] - 'a'];
201 if (ToLower(yytext[0]) != ToLower(PieceToChar(piece)))
202 return (int) IllegalMove;
204 result = LegalityTest(boards[yyboardindex],
205 PosFlags(yyboardindex), EP_UNKNOWN,
206 currentMoveString[1] - '1',
207 currentMoveString[0] - 'a',
208 currentMoveString[3] - '1',
209 currentMoveString[2] - 'a',
210 currentMoveString[4]);
212 if (currentMoveString[4] == NULLCHAR &&
213 (result == WhitePromotionQueen || result == BlackPromotionQueen)) {
214 currentMoveString[4] = 'q';
215 currentMoveString[5] = NULLCHAR;
221 [a-h][1-8][xX:-]?[a-h][1-8](=?\(?[RrBbNnQqKk]\)?)? {
223 * Simple algebraic move, possibly with promotion
228 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
230 /* remove the [xX:-] */
231 if ((yytext[2] == 'x') || (yytext[2] == 'X') ||
232 (yytext[2] == '-') || (yytext[2] == ':')) skip = 1;
234 currentMoveString[0] = yytext[0];
235 currentMoveString[1] = yytext[1];
236 currentMoveString[2] = yytext[2+skip];
237 currentMoveString[3] = yytext[3+skip];
238 currentMoveString[4] = NULLCHAR;
240 if (yyleng-skip > 4) {
241 if (yytext[yyleng-1] == ')') {
242 currentMoveString[4] = ToLower(yytext[yyleng-2]);
244 currentMoveString[4] = ToLower(yytext[yyleng-1]);
246 currentMoveString[5] = NULLCHAR;
249 result = LegalityTest(boards[yyboardindex],
250 PosFlags(yyboardindex), EP_UNKNOWN,
251 currentMoveString[1] - '1',
252 currentMoveString[0] - 'a',
253 currentMoveString[3] - '1',
254 currentMoveString[2] - 'a',
255 currentMoveString[4]);
257 if (currentMoveString[4] == NULLCHAR &&
258 (result == WhitePromotionQueen || result == BlackPromotionQueen)) {
259 currentMoveString[4] = 'q';
260 currentMoveString[5] = NULLCHAR;
266 [a-h][1-8](=?\(?[RrBbNnQqKk]\)?)? {
268 * Pawn move, possibly with promotion
270 DisambiguateClosure cl;
273 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
276 if (yytext[2] == '=') skip++;
277 if (yytext[2+skip] == '(') skip++;
279 cl.pieceIn = WhiteOnMove(yyboardindex) ? WhitePawn : BlackPawn;
281 cl.ffIn = yytext[0] - 'a';
282 cl.rtIn = yytext[1] - '1';
283 cl.ftIn = yytext[0] - 'a';
284 cl.promoCharIn = yytext[2+skip];
285 Disambiguate(boards[yyboardindex],
286 PosFlags(yyboardindex), EP_UNKNOWN, &cl);
288 currentMoveString[0] = cl.ff + 'a';
289 currentMoveString[1] = cl.rf + '1';
290 currentMoveString[2] = cl.ft + 'a';
291 currentMoveString[3] = cl.rt + '1';
292 currentMoveString[4] = cl.promoChar;
293 currentMoveString[5] = NULLCHAR;
295 return (int) cl.kind;
299 (ab|bc|cd|de|ef|fg|gh|hg|gf|fe|ed|dc|cb|ba|([a-h][xX:-][a-h]))(=?\(?[RrBbNnQqKk]\)?)?(ep|"e.p.")? {
301 * Pawn capture, possibly with promotion, possibly ambiguous
303 DisambiguateClosure cl;
304 int skip1 = 0, skip2 = 0;
306 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
308 /* remove trailing ep or e.p. (nonstandard PGN) */
309 if (yytext[yyleng-1] == 'p') {
311 yytext[yyleng] = NULLCHAR;
312 } else if (yytext[yyleng-1] == '.') {
314 yytext[yyleng] = NULLCHAR;
317 /* remove the [xX:-] and =() */
318 if ((yytext[1] == 'x') || (yytext[1] == 'X')
319 || (yytext[1] == ':') || (yytext[1] == '-')) skip1 = 1;
320 if (yytext[2+skip1] == '=') skip2++;
321 if (yytext[2+skip1+skip2] == '(') skip2++;
323 cl.pieceIn = WhiteOnMove(yyboardindex) ? WhitePawn : BlackPawn;
325 cl.ffIn = yytext[0] - 'a';
327 cl.ftIn = yytext[1+skip1] - 'a';
328 cl.promoCharIn = yytext[2+skip1+skip2];
329 Disambiguate(boards[yyboardindex],
330 PosFlags(yyboardindex), EP_UNKNOWN, &cl);
332 currentMoveString[0] = cl.ff + 'a';
333 currentMoveString[1] = cl.rf + '1';
334 currentMoveString[2] = cl.ft + 'a';
335 currentMoveString[3] = cl.rt + '1';
336 currentMoveString[4] = cl.promoChar;
337 currentMoveString[5] = NULLCHAR;
339 return (int) cl.kind;
342 [a-h][xX:]?[a-h][1-8](=?\(?[RrBbNnQqKk]\)?)?(ep|"e.p.")? {
344 * unambiguously abbreviated Pawn capture, possibly with promotion
349 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
351 /* remove trailing ep or e.p. (nonstandard PGN) */
352 if (yytext[yyleng-1] == 'p') {
354 yytext[yyleng] = NULLCHAR;
355 } else if (yytext[yyleng-1] == '.') {
357 yytext[yyleng] = NULLCHAR;
360 /* remove the [xX:-] */
361 if ((yytext[1] == 'x') || (yytext[1] == 'X')
362 || (yytext[1] == ':') || (yytext[1] == '-')) skip = 1;
364 currentMoveString[0] = yytext[0];
365 currentMoveString[2] = yytext[1+skip];
366 currentMoveString[3] = yytext[2+skip];
367 if (WhiteOnMove(yyboardindex)) {
368 if (yytext[2+skip] == '1') return (int) ImpossibleMove;
369 currentMoveString[1] = yytext[2+skip] - 1;
371 if (yytext[2+skip] == '8') return (int) ImpossibleMove;
372 currentMoveString[1] = yytext[2+skip] + 1;
374 if (yyleng-skip > 3) {
375 if (yytext[yyleng-1] == ')')
376 currentMoveString[4] = ToLower(yytext[yyleng-2]);
378 currentMoveString[4] = ToLower(yytext[yyleng-1]);
379 currentMoveString[5] = NULLCHAR;
381 currentMoveString[4] = NULLCHAR;
384 result = LegalityTest(boards[yyboardindex],
385 PosFlags(yyboardindex), EP_UNKNOWN,
386 currentMoveString[1] - '1',
387 currentMoveString[0] - 'a',
388 currentMoveString[3] - '1',
389 currentMoveString[2] - 'a',
390 currentMoveString[4]);
392 if (currentMoveString[4] == NULLCHAR &&
393 (result == WhitePromotionQueen || result == BlackPromotionQueen)) {
394 currentMoveString[4] = 'q';
395 currentMoveString[5] = NULLCHAR;
398 if (result != IllegalMove) return (int) result;
400 /* Special case: improperly written en passant capture */
401 if (WhiteOnMove(yyboardindex)) {
402 if (currentMoveString[3] == '5') {
403 currentMoveString[1] = '5';
404 currentMoveString[3] = '6';
406 return (int) IllegalMove;
409 if (currentMoveString[3] == '4') {
410 currentMoveString[1] = '4';
411 currentMoveString[3] = '3';
413 return (int) IllegalMove;
417 result = LegalityTest(boards[yyboardindex],
418 PosFlags(yyboardindex), EP_UNKNOWN,
419 currentMoveString[1] - '1',
420 currentMoveString[0] - 'a',
421 currentMoveString[3] - '1',
422 currentMoveString[2] - 'a',
423 currentMoveString[4]);
425 if (result == WhiteCapturesEnPassant || result == BlackCapturesEnPassant)
428 return (int) IllegalMove;
431 [RrBbNnQqKk][xX:-]?[a-h][1-8] {
433 * piece move, possibly ambiguous
435 DisambiguateClosure cl;
438 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
440 /* remove the [xX:-] */
441 if ((yytext[1] == 'x') || (yytext[1] == 'X')
442 || (yytext[1] == ':') || (yytext[1] == '-')) skip = 1;
444 if (WhiteOnMove(yyboardindex)) {
445 cl.pieceIn = CharToPiece(ToUpper(yytext[0]));
447 cl.pieceIn = CharToPiece(ToLower(yytext[0]));
451 cl.rtIn = yytext[2+skip] - '1';
452 cl.ftIn = yytext[1+skip] - 'a';
453 cl.promoCharIn = NULLCHAR;
454 Disambiguate(boards[yyboardindex],
455 PosFlags(yyboardindex), EP_UNKNOWN, &cl);
457 currentMoveString[0] = cl.ff + 'a';
458 currentMoveString[1] = cl.rf + '1';
459 currentMoveString[2] = cl.ft + 'a';
460 currentMoveString[3] = cl.rt + '1';
461 currentMoveString[4] = cl.promoChar;
462 currentMoveString[5] = NULLCHAR;
464 return (int) cl.kind;
467 [RrBbNnQqKk][a-h1-8][xX:-]?[a-h][1-8] {
469 * piece move with rank or file disambiguator
471 DisambiguateClosure cl;
474 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
476 /* remove the [xX:-] */
477 if ((yytext[2] == 'x') || (yytext[2] == 'X')
478 || (yytext[2] == ':') || (yytext[2] == '-')) skip = 1;
480 if (WhiteOnMove(yyboardindex)) {
481 cl.pieceIn = CharToPiece(ToUpper(yytext[0]));
483 cl.pieceIn = CharToPiece(ToLower(yytext[0]));
485 if (isalpha(yytext[1])) {
487 cl.ffIn = yytext[1] - 'a';
489 cl.rfIn = yytext[1] - '1';
492 cl.rtIn = yytext[3+skip] - '1';
493 cl.ftIn = yytext[2+skip] - 'a';
494 cl.promoCharIn = NULLCHAR;
495 Disambiguate(boards[yyboardindex],
496 PosFlags(yyboardindex), EP_UNKNOWN, &cl);
498 currentMoveString[0] = cl.ff + 'a';
499 currentMoveString[1] = cl.rf + '1';
500 currentMoveString[2] = cl.ft + 'a';
501 currentMoveString[3] = cl.rt + '1';
502 currentMoveString[4] = cl.promoChar;
503 currentMoveString[5] = NULLCHAR;
505 return (int) cl.kind;
508 000|0-0-0|ooo|OOO|o-o-o|O-O-O {
511 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
513 if (WhiteOnMove(yyboardindex)) {
514 if (boards[yyboardindex][0][3] == WhiteKing) {
515 /* ICS wild castling */
516 strcpy(currentMoveString, "d1f1");
522 strcpy(currentMoveString, "e1c1");
529 if (boards[yyboardindex][7][3] == BlackKing) {
530 /* ICS wild castling */
531 strcpy(currentMoveString, "d8f8");
537 strcpy(currentMoveString, "e8c8");
544 return (int) LegalityTest(boards[yyboardindex],
545 PosFlags(yyboardindex), EP_UNKNOWN,
546 rf, ff, rt, ft, NULLCHAR);
549 00|0-0|oo|OO|o-o|O-O {
552 if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
554 if (WhiteOnMove(yyboardindex)) {
555 if (boards[yyboardindex][0][3] == WhiteKing) {
556 /* ICS wild castling */
557 strcpy(currentMoveString, "d1b1");
563 strcpy(currentMoveString, "e1g1");
570 if (boards[yyboardindex][7][3] == BlackKing) {
571 /* ICS wild castling */
572 strcpy(currentMoveString, "d8b8");
578 strcpy(currentMoveString, "e8g8");
585 return (int) LegalityTest(boards[yyboardindex],
586 PosFlags(yyboardindex), EP_UNKNOWN,
587 rf, ff, rt, ft, NULLCHAR);
590 [PpNnBbRrQq]@[a-h][1-8] {
591 /* Bughouse piece drop. No legality checking for now. */
592 currentMoveString[1] = '@';
593 currentMoveString[2] = yytext[2];
594 currentMoveString[3] = yytext[3];
595 currentMoveString[4] = NULLCHAR;
596 if (WhiteOnMove(yyboardindex)) {
597 currentMoveString[0] = ToUpper(yytext[0]);
598 return (int) WhiteDrop;
600 currentMoveString[0] = ToLower(yytext[0]);
601 return (int) BlackDrop;
606 if (WhiteOnMove(yyboardindex))
607 return (int) BlackWins;
609 return (int) WhiteWins;
612 (([Ww](hite)?)|([Bb](lack)?))" "(([Rr]esign)|([Ff]orfeit))(s|ed)? {
613 return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins);
616 (([Ww](hite)?)|([Bb](lack)?))" "[Dd]isconnect(s|ed) {
617 return (int) GameUnfinished;
621 return (int) GameIsDrawn;
625 return (int) GameIsDrawn;
629 if (WhiteOnMove(yyboardindex))
630 return (int) BlackWins;
632 return (int) WhiteWins;
636 if (WhiteOnMove(yyboardindex))
637 return (int) BlackWins;
639 return (int) WhiteWins;
642 [Dd]raw(n)?(" "by)?(" "[Rr]epetition)|(" "[Aa]gree(d|ment)) {
643 return (int) GameIsDrawn;
646 [Dd]raw(n)?(" (".*")")? {
647 return (int) GameIsDrawn;
650 (([Ww](hite)?)|([Bb](lack)?))" "([Mm]ate(s|ed)?)|([Ww][io]n(s)?.*) {
651 return (int) (ToUpper(yytext[0]) == 'W' ? WhiteWins : BlackWins);
654 (([Ww](hite)?)|([Bb](lack)?))" "([Mm]ate(s|ed)?)|([Ll]os[tes]+.*) {
655 return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins);
658 ("{"[^\}\n]*"} ")?(1-0|"1 - 0"|"1/0"|"1 / 0"|"1:0"|"1 : 0")(" (".*")"|" {".*"}")? {
659 return (int) WhiteWins;
662 ("{"[^\}\n]*"} ")?(0-1|"0 - 1"|"0/1"|"0 / 1"|"0:1"|"0 : 1")(" (".*")"|" {".*"}")? {
663 return (int) BlackWins;
666 ("{"[^\}\n]*"} ")?("1/2"|"1 / 2")(" "?[-:]" "?("1/2"|"1 / 2"))?(" (".*")"|" {".*"}")? {
667 return (int) GameIsDrawn;
670 ("{"[^\}\n]*"} ")?"*"(" (".*")"|" {".*"}")? {
671 return (int) GameUnfinished;
674 [1-9][0-9]*/"."?[ \t\n]*[a-hNnPpRrBQqKkOo] {
676 if ((yyleng == 1) && (yytext[0] == '1'))
677 return (int) MoveNumberOne;
680 \([0-9]+:[0-9][0-9](\.[0-9]+)?\)|\{[0-9]+:[0-9][0-9](\.[0-9]+)?\} {
681 /* elapsed time indication, e.g. (0:12) or {10:21.071} */
682 return (int) ElapsedTime;
686 /* position diagram enclosed in [-- --] */
687 return (int) PositionDiagram;
690 ^"{--------------"\n[^\}]*\n"--------------}"$ {
691 /* position diagram enclosed in {-- --} */
692 return (int) PositionDiagram;
695 \[[ \t\n]*[A-Za-z0-9][A-Za-z0-9_+#=-]*[ \t\n]*\"[^"]*\"[ \t\n]*\] {
699 [Gg](nu|NU)" "?[Cc](hess|HESS).*[Gg](ame|AME) {
700 return (int) GNUChessGame;
703 ^[#;%]" "[^ ]*(" game file"|" position file").*$ {
704 return (int) XBoardGame;
707 \$[0-9]+ { /* numeric annotation glyph */
711 \{[^\}]*\} { /* anything in {} */
712 return (int) Comment;
715 ;.*$ { /* ; to end of line */
716 return (int) Comment;
719 \[[^\]]*\] { /* anything in [] */
720 return (int) Comment;
723 \([^()]*(\([^()]*\)[^()]*)+[^()]*\) { /* nested () */
724 return (int) Comment;
727 \([^)][^)]+\) { /* >=2 chars in () */
728 return (int) Comment;
731 ^[-a-zA-Z0-9]+:" ".*(\n[ \t]+.*)* {
732 /* Skip mail headers */
736 /* Skip random words */
740 /* Skip everything else */
746 static char *StringToLex;
755 if (StringToLex != NULL) {
761 } else if (unputCount > 0) {
762 ret = unputBuffer[--unputCount];
774 * Return offset of next pattern within current file
778 int offset = ftell(lexFP) - unputCount;
786 static void output(ch)
789 fprintf(stderr, "PARSER BUG: unmatched character '%c' (0%o)\n",
793 static void unput(ch)
797 if (StringToLex != NULL) {
800 if (unputCount >= UNPUT_BUF_SIZE)
801 fprintf(stderr, "PARSER BUG: unput buffer overflow '%c' (0%o)\n",
803 unputBuffer[unputCount++] = ch;
807 /* Get ready to lex from a new file. Kludge below sticks
808 an artificial newline at the front of the file, which the
809 above grammar ignores, but which makes ^ at start of pattern
810 match at the real start of the file.
818 unput('\n'); /* kludge */
821 /* Get ready to lex from a string. ^ at start of pattern WON'T
822 match at the start of the string!
831 #endif /*!FLEX_SCANNER*/
834 void my_yy_input(buf, result, max_size)
841 if (StringToLex != NULL) {
843 while (*StringToLex != NULLCHAR) {
844 *buf++ = *StringToLex++;
850 count = fread(buf, 1, max_size, yyin);
860 static YY_BUFFER_STATE my_file_buffer = NULL;
863 Return offset of next pattern in the current file.
867 int pos = yy_c_buf_p - YY_CURRENT_BUFFER->yy_ch_buf;
869 return(ftell(YY_CURRENT_BUFFER->yy_input_file) -
877 if (my_file_buffer != NULL)
878 yy_delete_buffer(my_file_buffer);
880 my_file_buffer = yy_create_buffer(stdin, YY_BUF_SIZE);
881 yy_switch_to_buffer(my_file_buffer);
887 if (my_file_buffer != NULL)
888 yy_delete_buffer(my_file_buffer);
890 my_file_buffer = yy_create_buffer(f, YY_BUF_SIZE);
891 yy_switch_to_buffer(my_file_buffer);
893 #endif /*FLEX_SCANNER*/
900 /* Parse a move from the given string s */
901 /* ^ at start of pattern WON'T work here unless using flex */
902 ChessMove yylexstr(boardIndex, s)
907 char *oldStringToLex;
909 YY_BUFFER_STATE buffer, oldBuffer;
912 yyboardindex = boardIndex;
913 oldStringToLex = StringToLex;
916 buffer = yy_create_buffer(stdin, YY_BUF_SIZE);
917 oldBuffer = YY_CURRENT_BUFFER;
918 yy_switch_to_buffer(buffer);
919 #endif /*FLEX_SCANNER*/
921 ret = (ChessMove) yylex();
924 if (oldBuffer != NULL)
925 yy_switch_to_buffer(oldBuffer);
926 yy_delete_buffer(buffer);
927 #endif /*FLEX_SCANNER*/
928 StringToLex = oldStringToLex;