X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=parser.l;h=e78c23c0902977e6f2f1f5e0f653c1e3b8acbfb2;hb=3a11677c0e70fe1833016cbf9070c3d5df615112;hp=17d791567b16934e5db05a6abec6d427e3e7c682;hpb=91f35c4c0e1494e9711f26bb86f843e176c81321;p=xboard.git diff --git a/parser.l b/parser.l index 17d7915..e78c23c 100644 --- a/parser.l +++ b/parser.l @@ -178,7 +178,7 @@ extern void CopyBoard P((Board to, Board from)); %} %% -"+"?[A-Z][/]?[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=+])? { +"+"?[A-Z][/]?[a-l][0-9][xX:-]?[a-l][0-9](([=/]?\(?[A-Z]\)?)|[=+])? { /* * Fully-qualified algebraic move, possibly with promotion */ @@ -268,7 +268,7 @@ extern void CopyBoard P((Board to, Board from)); return (int) result; } -[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Za-z]\)?)|[=+])? { +[a-l][0-9][xX:-]?[a-l][0-9](([=/]?\(?[A-Za-z]\)?)|[=+])? { /* * Simple algebraic move, possibly with promotion * [HGM] Engine moves are received in this format, with lower-case promoChar! @@ -294,7 +294,7 @@ extern void CopyBoard P((Board to, Board from)); } else { c = currentMoveString[4] = ToLower(yytext[yyleng-1]); } - if(c == '+' && gameInfo.variant != VariantShogi) c = currentMoveString[4] = NULLCHAR; // + means check outside Shogi + if(c == '+' && gameInfo.variant != VariantShogi) currentMoveString[4] = NULLCHAR; // + means check outside Shogi currentMoveString[5] = NULLCHAR; } @@ -330,7 +330,7 @@ extern void CopyBoard P((Board to, Board from)); } else if(result == WhiteNonPromotion || result == BlackNonPromotion) currentMoveString[4] = '='; currentMoveString[5] = NULLCHAR; - } else if(appData.testLegality && // strip off unnecessary and false promo characters + } else if(appData.testLegality && gameInfo.variant != VariantSChess && // strip off unnecessary and false promo characters !(result == WhitePromotion || result == BlackPromotion || result == WhiteNonPromotion || result == BlackNonPromotion)) currentMoveString[4] = NULLCHAR; @@ -384,7 +384,7 @@ extern void CopyBoard P((Board to, Board from)); * Pawn move, possibly with promotion */ DisambiguateClosure cl; - int skip = 0; char c; + int skip = 0; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ @@ -425,7 +425,7 @@ extern void CopyBoard P((Board to, Board from)); * Pawn capture, possibly with promotion, possibly ambiguous */ DisambiguateClosure cl; - int skip1 = 0, skip2 = 0; char c; + int skip1 = 0, skip2 = 0; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ @@ -527,8 +527,6 @@ extern void CopyBoard P((Board to, Board from)); else c = currentMoveString[4] = ToLower(yytext[yyleng-1]); currentMoveString[5] = NULLCHAR; - if(c != '=' && c != '+' && CharToPiece(c) == EmptySquare) - return ImpossibleMove; if(c == '+' && gameInfo.variant != VariantShogi) c = currentMoveString[4] = NULLCHAR; // + means check outside Shogi } else { currentMoveString[4] = NULLCHAR; @@ -586,11 +584,15 @@ extern void CopyBoard P((Board to, Board from)); if (result == WhiteCapturesEnPassant || result == BlackCapturesEnPassant) return (int) result; - else + else { // [HGM] all very nice, but this messed up the input move that we might want to accept with legality testing off... + if (WhiteOnMove(yyboardindex)) // undo the damage + currentMoveString[1]--, currentMoveString[3]--; + else currentMoveString[1]++, currentMoveString[3]++; return (int) IllegalMove; + } } -"+"?[A-Z][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=+])? { +"+"?[A-Z][xX:-]?[a-l][0-9](([=/]?\(?[A-Z]\)?)|[=+])? { /* * piece move, possibly ambiguous */ @@ -618,7 +620,7 @@ extern void CopyBoard P((Board to, Board from)); cl.ftIn = yytext[1+skip] - AAA; cl.promoCharIn = NULLCHAR; - if(yyleng-skip > 3 && gameInfo.variant == VariantShogi) /* [HGM] can have Shogi-style promotion */ + if(yyleng-skip > 3 && (gameInfo.variant == VariantShogi || gameInfo.variant == VariantSChess)) /* [HGM] can have Shogi-style promotion */ cl.promoCharIn = yytext[yyleng-1-(yytext[yyleng-1]==')')]; if(cl.promoCharIn == '+' && gameInfo.variant != VariantShogi) cl.promoCharIn = NULLCHAR; // + means check outside Shogi @@ -647,7 +649,7 @@ extern void CopyBoard P((Board to, Board from)); return (int) cl.kind; } -"+"?[A-Z][a-l0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=+])? { +"+"?[A-Z][a-l0-9][xX:-]?[a-l][0-9](([=/]?\(?[A-Z]\)?)|[=+])? { /* * piece move with rank or file disambiguator */ @@ -685,7 +687,7 @@ extern void CopyBoard P((Board to, Board from)); cl.ftIn = yytext[2+skip] - AAA; cl.promoCharIn = NULLCHAR; - if(yyleng-skip > 4) /* [HGM] can have Shogi-style promotion */ + if(yyleng-skip > 4 && (gameInfo.variant == VariantShogi || gameInfo.variant == VariantSChess)) /* [HGM] can have Shogi-style promotion */ cl.promoCharIn = yytext[yyleng-1-(yytext[yyleng-1]==')')]; if(cl.promoCharIn == '+' && gameInfo.variant != VariantShogi) cl.promoCharIn = NULLCHAR; // + means check outside Shogi @@ -821,6 +823,9 @@ extern void CopyBoard P((Board to, Board from)); } [A-Za-z][@*][a-l][0-9] { + + if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ + /* Bughouse piece drop. */ currentMoveString[1] = '@'; currentMoveString[2] = yytext[2]; @@ -897,26 +902,27 @@ extern void CopyBoard P((Board to, Board from)); return (int) (ToUpper(yytext[0]) == 'W' ? BlackWins : WhiteWins); } -("{"[^\}\n]*"} ")?(1-0|"1 - 0"|"1/0"|"1 / 0"|"1:0"|"1 : 0")(" (".*")"|" {".*"}")? { +("{"[^\}]*"}"[ \n])?(1-0|"1 - 0"|"1/0"|"1 / 0"|"1:0"|"1 : 0")(" (".*")"|" {".*"}")? { return (int) WhiteWins; } -("{"[^\}\n]*"} ")?(0-1|"0 - 1"|"0/1"|"0 / 1"|"0:1"|"0 : 1")(" (".*")"|" {".*"}")? { +("{"[^\}]*"}"[ \n])?(0-1|"0 - 1"|"0/1"|"0 / 1"|"0:1"|"0 : 1")(" (".*")"|" {".*"}")? { return (int) BlackWins; } -("{"[^\}\n]*"} ")?("1/2"|"1 / 2")(" "?[-:]" "?("1/2"|"1 / 2"))?(" (".*")"|" {".*"}")? { +("{"[^\}]*"}"[ \n])?("1/2"|"1 / 2")(" "?[-:]" "?("1/2"|"1 / 2"))?(" (".*")"|" {".*"}")? { return (int) GameIsDrawn; } -("{"[^\}\n]*"} ")?"*"(" (".*")"|" {".*"}")? { +("{"[^\}]*"}"[ \n])?"*"(" (".*")"|" {".*"}")? { return (int) GameUnfinished; } -[1-9][0-9]*/"."?[ \t\n]*[a-lNnPpRrBQqKACFEWDGHOo] { +[1-9][0-9]*/"."?[ \t\n]*[a-lnprqoA-Z+] { /* move numbers */ if ((yyleng == 1) && (yytext[0] == '1')) return (int) MoveNumberOne; + else return (int) Nothing; // [HGM] make sure something is returned, for gathering parsed text } \([0-9]+:[0-9][0-9](\.[0-9]+)?\)|\{[0-9]+:[0-9][0-9](\.[0-9]+)?\} { @@ -962,24 +968,24 @@ extern void CopyBoard P((Board to, Board from)); return (int) Comment; } -\([^()]*(\([^()]*(\([^()]*(\([^()]*\)[^()]*)*\)[^()]*)*\)[^()]*)+[^()]*\) { /* very nested () */ - return (int) Comment; +\( { /* Opening parentheses */ + return (int) Open; } -\([^)][^)]+\) { /* >=2 chars in () */ - return (int) Comment; +\) { /* closing parentheses */ + return (int) Close; } ^[-a-zA-Z0-9]+:" ".*(\n[ \t]+.*)* { - /* Skip mail headers */ + return (int) Nothing; /* Skip mail headers */ } [a-zA-Z0-9'-]+ { - /* Skip random words */ + return (int) Nothing; /* Skip random words */ } .|\n { - /* Skip everything else */ + return (int) Nothing; /* Skip everything else */ } %% @@ -1160,7 +1166,7 @@ ChessMove yylexstr(boardIndex, s, text, len) yy_switch_to_buffer(buffer); #endif /*FLEX_SCANNER*/ - ret = (ChessMove) yylex(); + ret = (ChessMove) Myylex(); strncpy(text, yy_text, len-1); // [HGM] vari: yy_text is not available to caller after buffer switch ?!? text[len-1] = NULLCHAR; @@ -1173,3 +1179,23 @@ ChessMove yylexstr(boardIndex, s, text, len) return ret; } + +int Myylex() +{ // [HGM] wrapper for yylex, which treats nesting of parentheses + int symbol, nestingLevel = 0, i=0; + char *p; + static char buf[256*MSG_SIZ]; + buf[0] = NULLCHAR; + do { // eat away anything not at level 0 + symbol = yylex(); + if(symbol == Open) nestingLevel++; + if(nestingLevel) { // save all parsed text between (and including) the () + for(p=yytext; *p && i<256*MSG_SIZ-2;) buf[i++] = *p++; + buf[i] = NULLCHAR; + } + if(symbol == 0) break; // ran into EOF + if(symbol == Close) symbol = Comment, nestingLevel--; + } while(nestingLevel || symbol == Nothing); + yy_text = buf[0] ? buf : (char*)yytext; + return symbol; +}