00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PGNGRAMMAR_H
00025 #define PGNGRAMMAR_H
00026
00027 #ifndef USE_PCH
00028 #include "sys.h"
00029 #endif
00030
00031 #ifndef CWCHESS_PGN_ANALYSIS
00032 #include <boost/spirit/include/classic_spirit.hpp>
00033 #include <boost/spirit/include/classic_numerics.hpp>
00034 #endif
00035
00036 namespace cwchess {
00037 namespace pgn {
00038 namespace grammar {
00039
00040 namespace imp {
00041 }
00042
00043
00044 #define TRACE_PGN_GRAMMAR 1
00045 #define TRACE_PGN_WHITESPACE 0
00046 #define TRACE_PGN_PRINTABLE 0
00047 #define TRACE_PGN_ANNOTATION 0
00048 #define TRACE_PGN_INTEGER 0
00049 #define TRACE_PGN_COMMENT 0
00050 #define TRACE_PGN_SAN_MOVE 0
00051 #define TRACE_PGN_SAN_INTERNAL 0
00052 #define TRACE_PGN_PUNCTUATION_JUNK 0
00053
00054 class PgnGrammar : public boost::spirit::classic::grammar<PgnGrammar> {
00055 private:
00056 typedef PgnGrammar grammar_t;
00057
00058 public:
00059 PgnGrammar(void)
00060 {
00061 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "PgnGrammar", 1);
00062 }
00063
00064 public:
00065 template <typename ScannerT>
00066 struct definition {
00067
00068 typedef typename ScannerT::iteration_policy_t iteration_policy_t;
00069 typedef boost::spirit::classic::match_policy match_policy_t;
00070 typedef typename ScannerT::action_policy_t action_policy_t;
00071 typedef boost::spirit::classic::scanner_policies<iteration_policy_t, match_policy_t, action_policy_t> policies_t;
00072 typedef boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t> non_tree_scanner_t;
00073 typedef boost::spirit::classic::rule<non_tree_scanner_t> no_tree_rule_t;
00074
00075 typedef boost::spirit::classic::rule<ScannerT> rule_t;
00076
00077 boost::spirit::classic::uint_parser<unsigned, 10, 1, 3> uint3_p;
00078
00079
00080 rule_t leading_junk;
00081 rule_t file;
00082 rule_t rank;
00083 rule_t piece;
00084 rule_t check;
00085 rule_t punctuation_junk;
00086 rule_t tagname_begin;
00087 rule_t tagname_continuation;
00088 rule_t printable;
00089 rule_t printable_string;
00090 rule_t printable_comment;
00091 rule_t promotion;
00092 no_tree_rule_t blank;
00093 no_tree_rule_t white_space;
00094 no_tree_rule_t escaped_data;
00095 no_tree_rule_t eol;
00096 rule_t integer;
00097 rule_t square;
00098 rule_t disambiguation;
00099 rule_t string;
00100 rule_t tag_name;
00101 rule_t tag_value;
00102 rule_t game_termination;
00103 rule_t elipsis;
00104 rule_t move_number_indication;
00105 rule_t SAN_move;
00106 rule_t annotation;
00107 rule_t numeric_annotation_glyph;
00108 rule_t text_annotation1_junk;
00109 rule_t text_annotation2_junk;
00110 rule_t comment;
00111 rule_t parenthesis_junk;
00112 rule_t tag_pair;
00113 rule_t tag_section;
00114 rule_t move;
00115 rule_t white_move;
00116 rule_t last_white_move;
00117 rule_t arena_junk;
00118 rule_t black_move;
00119 rule_t movetext_section_white;
00120 rule_t movetext_section_black;
00121 rule_t white_black_move;
00122 rule_t recursive_variation_white;
00123 rule_t recursive_variation_black;
00124 rule_t wrong_color_white_junk;
00125 rule_t wrong_color_black_junk;
00126 rule_t movetext_section;
00127 rule_t PGN_game;
00128 rule_t PGN_database;
00129
00130
00131
00132 rule_t const& start(void) const { return PGN_database; }
00133
00134 definition(PgnGrammar const& self)
00135 {
00136 using namespace boost::spirit::classic;
00137
00138 leading_junk
00139 =
00140 * ((*~ch_p('\n') >>* ch_p('\n')) - tag_pair)
00141 ;
00142
00143 file
00144 =
00145 range_p('a', 'h')
00146 ;
00147
00148 rank
00149 =
00150 range_p('1', '8')
00151 ;
00152
00153 piece
00154 =
00155 ch_p('R')
00156 | ch_p('N')
00157 | ch_p('B')
00158 | ch_p('Q')
00159 | ch_p('K')
00160 ;
00161
00162 check
00163 =
00164 ch_p('+')
00165 | ch_p('#')
00166 ;
00167
00168 punctuation_junk
00169 =
00170 ch_p(',')
00171 | ch_p(';')
00172 ;
00173
00174 tagname_begin
00175 =
00176 alnum_p
00177 ;
00178
00179 tagname_continuation
00180 =
00181 alnum_p
00182 | ch_p('_')
00183 ;
00184
00185 printable
00186 =
00187 range_p(32, 126)
00188 | range_p(-96, -1)
00189 ;
00190
00191 printable_string
00192 =
00193 ( range_p(35, 91)
00194 | ch_p(' ')
00195 | range_p(93, 126)
00196 | ch_p('!')
00197 | range_p(-96, -1)
00198 )
00199 | ( ch_p('\\') >> (ch_p('\\') | ch_p('"')))
00200 ;
00201
00202 printable_comment
00203 =
00204 range_p(32, 124)
00205 | ch_p('~')
00206 | blank
00207 | eol
00208 | range_p(-96, -1)
00209 ;
00210
00211 promotion
00212 =
00213 ch_p('=') >> piece
00214 ;
00215
00216 blank
00217 =
00218 ch_p(' ')
00219 | ch_p('\t')
00220 | ch_p('\v')
00221 ;
00222
00223 white_space
00224 =
00225 blank >> !white_space
00226 | eol >> !white_space
00227 ;
00228
00229 escaped_data
00230 =
00231 ch_p('%') >>* (anychar_p - eol_p) >> eol_p
00232 ;
00233
00234 eol
00235 =
00236 eol_p >>* escaped_data
00237 ;
00238
00239 integer
00240 =
00241 uint3_p
00242 ;
00243
00244 square
00245 =
00246 file >> rank
00247 ;
00248
00249 disambiguation
00250 =
00251 file
00252 | rank
00253 | square
00254 ;
00255
00256 string
00257 =
00258 ch_p('"') >>* printable_string >> ch_p('"')
00259 ;
00260
00261 tag_name
00262 =
00263 tagname_begin >>* tagname_continuation
00264 ;
00265
00266 tag_value
00267 =
00268 string
00269 ;
00270
00271 game_termination
00272 =
00273 str_p("1-0")
00274 | str_p("0-1")
00275 | str_p("1/2-1/2")
00276 | ch_p('*')
00277 ;
00278
00279 elipsis
00280 =
00281 str_p("..") >> !ch_p('.')
00282 ;
00283
00284 move_number_indication
00285 =
00286 integer >> (ch_p('.') | ch_p(' '))
00287 ;
00288
00289 SAN_move
00290 =
00291 ( piece >> !ch_p('x') >> square
00292 | piece >> disambiguation >> !ch_p('x') >> square
00293 | file >> ch_p('x') >> square >> !promotion
00294 | square >> !promotion
00295 | str_p("O-O-O")
00296 | str_p("O-O")
00297 | str_p("0-0-0")
00298 | str_p("0-0")
00299 )
00300 >> !check
00301 ;
00302
00303 annotation
00304 =
00305 !(text_annotation1_junk >> !white_space) >>* (!comment >> (numeric_annotation_glyph | text_annotation2_junk) >> !white_space)
00306 ;
00307
00308 numeric_annotation_glyph
00309 =
00310 ch_p('$') >> uint3_p
00311 ;
00312
00313 text_annotation1_junk
00314 =
00315 ( ch_p('!')
00316 | ch_p('?')
00317 ) >>
00318 !( ch_p('!')
00319 | ch_p('?')
00320 )
00321 ;
00322
00323 text_annotation2_junk
00324 =
00325 ch_p('=') >> !( ch_p('-')
00326 | ch_p('+')
00327 )
00328 | ch_p('-') >> ( ch_p('=')
00329 | (!ch_p('/') >> ch_p('+'))
00330 )
00331 | ch_p('+') >> ( (!ch_p('/') >> ch_p('-'))
00332 | ch_p('=')
00333 )
00334 | ch_p('~')
00335 ;
00336
00337 comment
00338 =
00339 ch_p('{') >>* printable_comment >> ch_p('}') >> !white_space >> !comment
00340 | ch_p(';') >>* printable >> eol >> !white_space >> !comment
00341 | parenthesis_junk >> !white_space >> !comment
00342 ;
00343
00344
00345 parenthesis_junk
00346 =
00347 ch_p('(') >> !white_space >> ch_p('{') >>* printable_comment >> ch_p('}') >> !white_space >> ch_p(')')
00348 ;
00349
00350 tag_pair
00351 =
00352 ch_p('[') >> !white_space >> tag_name >> !white_space >> tag_value >> !white_space >> ch_p(']') >> !white_space
00353 ;
00354
00355 tag_section
00356 =
00357 tag_pair >> !tag_section
00358 ;
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 move
00378 =
00379 SAN_move >> !punctuation_junk >> !white_space >> !(annotation >> !white_space)
00380 ;
00381
00382 white_move
00383 =
00384 move_number_indication >> !white_space >> move >> !comment >>* recursive_variation_white
00385 ;
00386
00387 last_white_move
00388 =
00389 white_move
00390 | arena_junk
00391 ;
00392
00393 arena_junk
00394 =
00395 move_number_indication >> !white_space >> elipsis >> !white_space >> comment
00396 ;
00397
00398 black_move
00399 =
00400 move_number_indication >> !white_space >> elipsis >> !white_space >> move >> !comment >>* recursive_variation_black
00401 ;
00402
00403 movetext_section_white
00404 =
00405 white_black_move >>* white_black_move >> !last_white_move
00406 | last_white_move
00407 ;
00408
00409 movetext_section_black
00410 =
00411 black_move >> !movetext_section_white
00412 ;
00413
00414 white_black_move
00415 =
00416 move_number_indication >> !white_space >> move >> !comment >> move >> !comment >>* recursive_variation_black
00417 | white_move >> black_move
00418 ;
00419
00420 recursive_variation_white
00421 =
00422 ch_p('(') >> !white_space >> !comment >> (movetext_section_white | wrong_color_black_junk) >> ch_p(')') >> !white_space >> !comment
00423 ;
00424
00425 recursive_variation_black
00426 =
00427 ch_p('(') >> !white_space >> !comment >> (movetext_section_black | wrong_color_white_junk) >> ch_p(')') >> !white_space >> !comment
00428 ;
00429
00430 wrong_color_white_junk
00431 =
00432 movetext_section_white
00433 ;
00434
00435 wrong_color_black_junk
00436 =
00437 movetext_section_black
00438 ;
00439
00440 movetext_section
00441 =
00442 !comment >> (movetext_section_white | movetext_section_black)
00443 ;
00444
00445 PGN_game
00446 =
00447 !tag_section >> !movetext_section >> game_termination >> !white_space >> !comment
00448 ;
00449
00450 PGN_database
00451 =
00452 !white_space >> leading_junk >>* PGN_game;
00453 ;
00454
00455
00456 BOOST_SPIRIT_DEBUG_TRACE_RULE(leading_junk, TRACE_PGN_GRAMMAR);
00457 BOOST_SPIRIT_DEBUG_TRACE_RULE(file, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00458 BOOST_SPIRIT_DEBUG_TRACE_RULE(rank, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00459 BOOST_SPIRIT_DEBUG_TRACE_RULE(piece, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00460 BOOST_SPIRIT_DEBUG_TRACE_RULE(check, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00461 BOOST_SPIRIT_DEBUG_TRACE_RULE(punctuation_junk, TRACE_PGN_GRAMMAR & TRACE_PGN_PUNCTUATION_JUNK);
00462 BOOST_SPIRIT_DEBUG_TRACE_RULE(tagname_begin, TRACE_PGN_GRAMMAR);
00463 BOOST_SPIRIT_DEBUG_TRACE_RULE(tagname_continuation, TRACE_PGN_GRAMMAR);
00464 BOOST_SPIRIT_DEBUG_TRACE_RULE(printable, TRACE_PGN_GRAMMAR & TRACE_PGN_PRINTABLE);
00465 BOOST_SPIRIT_DEBUG_TRACE_RULE(printable_string, TRACE_PGN_GRAMMAR & TRACE_PGN_PRINTABLE);
00466 BOOST_SPIRIT_DEBUG_TRACE_RULE(printable_comment, TRACE_PGN_GRAMMAR & TRACE_PGN_PRINTABLE);
00467 BOOST_SPIRIT_DEBUG_TRACE_RULE(promotion, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00468 BOOST_SPIRIT_DEBUG_TRACE_RULE(blank, TRACE_PGN_GRAMMAR & TRACE_PGN_WHITESPACE);
00469 BOOST_SPIRIT_DEBUG_TRACE_RULE(white_space, TRACE_PGN_GRAMMAR & TRACE_PGN_WHITESPACE);
00470 BOOST_SPIRIT_DEBUG_TRACE_RULE(escaped_data, TRACE_PGN_GRAMMAR & TRACE_PGN_WHITESPACE);
00471 BOOST_SPIRIT_DEBUG_TRACE_RULE(eol, TRACE_PGN_GRAMMAR & TRACE_PGN_WHITESPACE);
00472 BOOST_SPIRIT_DEBUG_TRACE_RULE(integer, TRACE_PGN_GRAMMAR & TRACE_PGN_INTEGER);
00473 BOOST_SPIRIT_DEBUG_TRACE_RULE(square, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00474 BOOST_SPIRIT_DEBUG_TRACE_RULE(disambiguation, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_INTERNAL);
00475 BOOST_SPIRIT_DEBUG_TRACE_RULE(string, TRACE_PGN_GRAMMAR);
00476 BOOST_SPIRIT_DEBUG_TRACE_RULE(tag_name, TRACE_PGN_GRAMMAR);
00477 BOOST_SPIRIT_DEBUG_TRACE_RULE(tag_value, TRACE_PGN_GRAMMAR);
00478 BOOST_SPIRIT_DEBUG_TRACE_RULE(game_termination, TRACE_PGN_GRAMMAR);
00479 BOOST_SPIRIT_DEBUG_TRACE_RULE(elipsis, TRACE_PGN_GRAMMAR);
00480 BOOST_SPIRIT_DEBUG_TRACE_RULE(move_number_indication, TRACE_PGN_GRAMMAR);
00481 BOOST_SPIRIT_DEBUG_TRACE_RULE(SAN_move, TRACE_PGN_GRAMMAR & TRACE_PGN_SAN_MOVE);
00482 BOOST_SPIRIT_DEBUG_TRACE_RULE(annotation, TRACE_PGN_GRAMMAR);
00483 BOOST_SPIRIT_DEBUG_TRACE_RULE(numeric_annotation_glyph, TRACE_PGN_GRAMMAR & TRACE_PGN_ANNOTATION);
00484 BOOST_SPIRIT_DEBUG_TRACE_RULE(text_annotation1_junk, TRACE_PGN_GRAMMAR & TRACE_PGN_ANNOTATION);
00485 BOOST_SPIRIT_DEBUG_TRACE_RULE(text_annotation2_junk, TRACE_PGN_GRAMMAR & TRACE_PGN_ANNOTATION);
00486 BOOST_SPIRIT_DEBUG_TRACE_RULE(comment, TRACE_PGN_GRAMMAR & TRACE_PGN_COMMENT);
00487 BOOST_SPIRIT_DEBUG_TRACE_RULE(parenthesis_junk, TRACE_PGN_GRAMMAR & TRACE_PGN_COMMENT);
00488 BOOST_SPIRIT_DEBUG_TRACE_RULE(tag_pair, TRACE_PGN_GRAMMAR);
00489 BOOST_SPIRIT_DEBUG_TRACE_RULE(tag_section, TRACE_PGN_GRAMMAR);
00490 BOOST_SPIRIT_DEBUG_TRACE_RULE(move, TRACE_PGN_GRAMMAR);
00491 BOOST_SPIRIT_DEBUG_TRACE_RULE(white_move, TRACE_PGN_GRAMMAR);
00492 BOOST_SPIRIT_DEBUG_TRACE_RULE(last_white_move, TRACE_PGN_GRAMMAR);
00493 BOOST_SPIRIT_DEBUG_TRACE_RULE(arena_junk, TRACE_PGN_GRAMMAR);
00494 BOOST_SPIRIT_DEBUG_TRACE_RULE(black_move, TRACE_PGN_GRAMMAR);
00495 BOOST_SPIRIT_DEBUG_TRACE_RULE(movetext_section_white, TRACE_PGN_GRAMMAR);
00496 BOOST_SPIRIT_DEBUG_TRACE_RULE(movetext_section_black, TRACE_PGN_GRAMMAR);
00497 BOOST_SPIRIT_DEBUG_TRACE_RULE(white_black_move, TRACE_PGN_GRAMMAR);
00498 BOOST_SPIRIT_DEBUG_TRACE_RULE(recursive_variation_white, TRACE_PGN_GRAMMAR);
00499 BOOST_SPIRIT_DEBUG_TRACE_RULE(recursive_variation_black, TRACE_PGN_GRAMMAR);
00500 BOOST_SPIRIT_DEBUG_TRACE_RULE(wrong_color_white_junk, TRACE_PGN_GRAMMAR);
00501 BOOST_SPIRIT_DEBUG_TRACE_RULE(wrong_color_black_junk, TRACE_PGN_GRAMMAR);
00502 BOOST_SPIRIT_DEBUG_TRACE_RULE(movetext_section, TRACE_PGN_GRAMMAR);
00503 BOOST_SPIRIT_DEBUG_TRACE_RULE(PGN_game, TRACE_PGN_GRAMMAR);
00504 BOOST_SPIRIT_DEBUG_TRACE_RULE(PGN_database, TRACE_PGN_GRAMMAR);
00505
00506 }
00507 };
00508 };
00509
00510 }
00511 }
00512 }
00513
00514 #endif // PGNGRAMMAR_H