Removed all old variants.
[tagua/yd.git] / src / pgnparser.cpp
blob9d2e96709a012cba8337257f77c380d71984531e
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include <iostream>
12 #include <QRegExp>
13 #include "pgnparser.h"
14 #include "common.h"
16 QRegExp PGN::number("^(\\d+)(?:(?:\\.\\s+)?(\\.\\.\\.)|\\.?)?");
17 QRegExp PGN::begin_var("^\\(");
18 QRegExp PGN::end_var("^\\)");
19 QRegExp PGN::comment("^\\{[^}]*\\}");
20 QRegExp PGN::comment2("^;[^\\n]*\\n");
21 QRegExp PGN::wsPattern("^\\s+");
22 QRegExp PGN::tag("^\\[(\\S+)\\s+\"((?:[^\"]|\\\\\")*)\"\\]");
23 QRegExp PGN::move_tag("^\\$(\\d+)");
24 QRegExp PGN::move("^[^$\\{\\(\\[\\s][^\\{\\(\\[\\s]*");
25 QRegExp PGN::result("^(?:\\*|1-0|0-1|1/2-1/2)");
26 QRegExp PGN::time("^\\([\\d:.]*\\)");
27 QRegExp PGN::eol("(?:[ \t]\r?\n\r?|\r?\n\r?[ \t]|\r?\n\r?)");
29 bool PGN::tryRegExp(QRegExp& re, const QString& str, int& offset) {
30 if (re.indexIn(str, offset, QRegExp::CaretAtOffset) != -1) {
31 offset += re.matchedLength();
32 return true;
34 else return false;
37 #define IGNORE(re) if (tryRegExp((re), pgn, offset)) continue;
38 bool PGN::parse(const QString& pgn) {
39 int offset = 0;
41 while (offset < pgn.length()) {
42 IGNORE(wsPattern);
44 // read result
45 if (result.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
46 QString res = pgn.mid(offset, result.matchedLength());
47 offset += result.matchedLength();
48 return true;
51 IGNORE(comment2);
52 IGNORE(time);
54 // read comment
55 if (tag.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
56 m_tags[tag.cap(1)] = tag.cap(2);
57 offset += tag.matchedLength();
58 continue;
61 // read comment
62 if (comment.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
63 m_entries.push_back(pgn.mid(offset + 1, comment.matchedLength() - 2).replace(eol, " "));
64 offset += comment.matchedLength();
65 continue;
68 // read var, 1
69 if (begin_var.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
70 m_entries.push_back(BeginVariation());
71 offset += begin_var.matchedLength();
72 continue;
75 // read var, 2
76 if (end_var.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
77 m_entries.push_back(EndVariation());
78 offset += end_var.matchedLength();
79 continue;
82 // read move tag
83 if (move_tag.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
84 // not nothing :)
85 tryRegExp(wsPattern, pgn, offset);
88 int num = 0;
90 // read number, and do not continue
91 if (number.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
92 num = number.cap(1).toInt()*2 + (number.cap(2).isEmpty() ? 0 : 1);
93 offset += number.matchedLength();
94 tryRegExp(wsPattern, pgn, offset);
97 // read move
98 if (move.indexIn(pgn, offset, QRegExp::CaretAtOffset) != -1) {
99 m_entries.push_back(Move(num, move.cap(0)));
100 offset += move.matchedLength();
101 continue;
104 // parse error!
105 std::cout << "pgn parse error! at" << pgn.mid(offset, 100) << std::endl;
106 return false;
109 return true;
111 #undef IGNORE
113 PGN::PGN(const QString& str) {
114 m_valid = parse(str);