Π€ΡΠ½ΠΊΡΠΈΡ value() ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π° Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ const. ΠΡΠΈ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ cachedValue ΠΈ cacheIsValid ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ mutable, ΡΡΠΎΠ±Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ» Π½Π°ΠΌ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Π² ΡΡΠ½ΠΊΡΠΈΡΡ ΡΠΈΠΏΠ° const. ΠΠΎΠΆΠ΅Ρ ΠΏΠΎΠΊΠ°Π·Π°ΡΡΡΡ Π·Π°ΠΌΠ°Π½ΡΠΈΠ²ΠΎΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ value() Π½Π΅ ΡΠΈΠΏΠ° const ΠΈ ΡΠ΄Π°Π»ΠΈΡΡ ΠΊΠ»ΡΡΠ΅Π²ΡΠ΅ ΡΠ»ΠΎΠ²Π° mutable, Π½ΠΎ ΡΡΠΎ Π½Π΅ ΠΏΡΠΎΠΏΡΡΡΠΈΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ value() ΠΈΠ· data() β ΡΡΠ½ΠΊΡΠΈΠΈ Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ const.
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠΈΡΠ°ΡΡ, ΡΡΠΎ ΠΌΡ Π·Π°Π²Π΅ΡΡΠΈΠ»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΠ»Π΅ΠΊΡΡΠΎΠ½Π½Π°Ρ ΡΠ°Π±Π»ΠΈΡΠ°, Π΅ΡΠ»ΠΈ Π½Π΅ Π±ΡΠ°ΡΡ Π² ΡΠ°ΡΡΠ΅Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ· ΡΠΎΡΠΌΡΠ». Π ΠΎΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΠ°ΡΡΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ°Π·Π΄Π΅Π»Π° ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ evalExpression() ΠΈ Π΄Π²Π΅ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ evalTerm() ΠΈ evalFactor(). ΠΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ»ΠΎΠΆΠ΅Π½, Π½ΠΎ ΠΎΠ½ Π²ΠΊΠ»ΡΡΠ΅Π½ ΡΡΠ΄Π°, ΡΡΠΎΠ±Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π»ΠΎ Π·Π°ΠΊΠΎΠ½ΡΠ΅Π½Π½ΡΠΉ Π²ΠΈΠ΄. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠΎΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ Π½Π΅ ΠΎΡΠ½ΠΎΡΠΈΡΡΡ ΠΊ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΏΠΎΠΊΠΎΠΉΠ½ΠΎ Π΅Π³ΠΎ ΠΏΡΠΎΠΏΡΡΡΠΈΡΡ ΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ ΡΡΠ΅Π½ΠΈΠ΅ Ρ Π³Π»Π°Π²Ρ 5.
Π€ΡΠ½ΠΊΡΠΈΡ evalExpression() Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈΠ· ΡΡΠ΅ΠΉΠΊΠΈ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΡΠ°Π±Π»ΠΈΡΡ. ΠΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠ΅ΡΠΌΠΎΠ², ΡΠ°Π·Π΄Π΅Π»Π΅Π½Π½ΡΡ Π·Π½Π°ΠΊΠ°ΠΌΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Β«+Β» ΠΈΠ»ΠΈ Β«βΒ». Π’Π΅ΡΠΌΡ ΡΠΎΡΡΠΎΡΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠ°ΠΊΡΠΎΡΠΎΠ² (factors), ΡΠ°Π·Π΄Π΅Π»Π΅Π½Π½ΡΡ Π·Π½Π°ΠΊΠ°ΠΌΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Β«*Β» ΠΈΠ»ΠΈ Β«/Β». Π Π°Π·Π±ΠΈΠ²Π°Ρ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ Π½Π° ΡΠ΅ΡΠΌΡ, Π° ΡΠ΅ΡΠΌΡ Π½Π° ΡΠ°ΠΊΡΠΎΡΡ, ΠΌΡ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅ΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Β«2*C5+D6Β» ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ΅ΡΠΌ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄Π΅Ρ Β«2*C5Β», Π° Π²ΡΠΎΡΠΎΠΉ ΡΠ΅ΡΠΌ β Β«D6Β». Β«2*C5Β» ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΡΠΌΠΎΠΌ, ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ°ΠΊΡΠΎΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄Π΅Ρ Β«2Β», Π° Π²ΡΠΎΡΠΎΠΉ ΡΠ°ΠΊΡΠΎΡ β Β«C5Β»; Β«D6Β» ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΊΡΠΎΡΠ° β Β«D6Β». Π€Π°ΠΊΡΠΎΡΠΎΠΌ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΡΠΈΡΠ»ΠΎ (Β«2Β»), ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΠΉΠΊΠΈ (Β«C5Β») ΠΈΠ»ΠΈ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΡΠΊΠΎΠ±ΠΊΠ°Ρ , ΠΏΠ΅ΡΠ΅Π΄ ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠΎΡΡΡ Π·Π½Π°ΠΊ ΠΌΠΈΠ½ΡΡΠ°.
Π ΠΈΡ. 4.10. ΠΠ»ΠΎΠΊβΡΡ Π΅ΠΌΠ° ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΡΠ°Π±Π»ΠΈΡΡ.
ΠΠ»ΠΎΠΊβΡΡ Π΅ΠΌΠ° ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΡΠ°Π±Π»ΠΈΡΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π° Π½Π° ΡΠΈΡ. 4.10. ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° (Expression, Term ΠΈ Factor β Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, ΡΠ΅ΡΠΌ ΠΈ ΡΠ°ΠΊΡΠΎΡ) ΠΈΠΌΠ΅Π΅ΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡβΡΠ»Π΅Π½, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π΅Π³ΠΎ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ· ΠΈ ΡΡΡΡΠΊΡΡΡΠ° ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΡΠ΅Π½Ρ Ρ ΠΎΡΠΎΡΠΎ ΠΎΡΡΠ°ΠΆΠ°Π΅Ρ Π΅Π³ΠΎ Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΡ. ΠΠΎΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΡ Π½Π°Π·ΡΠ²Π°ΡΡΡΡ ΠΏΠ°ΡΡΠ΅ΡΠ°ΠΌΠΈ Ρ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΡΠΌ ΡΠΏΡΡΠΊΠΎΠΌ (recursiveβdescent parsers).
ΠΠ°Π²Π°ΠΉΡΠ΅ Π½Π°ΡΠ½Π΅ΠΌ Ρ evalExpression(), ΡΠΎ Π΅ΡΡΡ Ρ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°Π·Π±ΠΎΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ:
01 QVariant Cell::evalExpression(const QString &str, int &pos) const
02 {
03 QVariant result = evalTerm(str, pos);
04 while (str[pos] != QChar::Null) {
05 QChar op = str[pos];
06 if (op != '+' && op != '-') return result;
07 ++pos;
08 QVariant term = evalTerm(str, pos);
09 if (result.type() == QVariant::Double
10 && term.type() == QVariant::Double) {
11 if (op == '+') {
12 result = result.toDouble() + term.toDouble();
13 } else {
14 result= result.toDouble() - term.toDouble();
15 }
16 } else {
17 result = Invalid;
18 }
19 }
20 return result;
21 }
ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , ΠΌΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ evalTerm() Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΡΠ΅ΡΠΌΠ°. ΠΡΠ»ΠΈ Π·Π° Π½ΠΈΠΌ ΠΈΠ΄Π΅Ρ ΡΠΈΠΌΠ²ΠΎΠ» Β«+Β» ΠΈΠ»ΠΈ Β«βΒ», ΠΌΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π²ΡΠΎΡΠΎΠΉ ΡΠ°Π· evalTerm(); Π² ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΡΠΌΠ°, ΠΈ ΠΌΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ Π΅Π³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π²ΡΠ΅Π³ΠΎ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ. ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΏΠ΅ΡΠ²ΡΡ Π΄Π²ΡΡ ΡΠ΅ΡΠΌΠΎΠ² ΠΌΡ Π²ΡΡΠΈΡΠ»ΡΠ΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ°. ΠΡΠ»ΠΈ ΠΏΡΠΈ ΠΎΡΠ΅Π½ΠΊΠ΅ ΠΎΠ±ΠΎΠΈΡ ΡΠ΅ΡΠΌΠΎΠ² ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π±ΡΠ΄ΡΡ ΠΈΠΌΠ΅ΡΡ ΡΠΈΠΏ double, ΠΌΡ ΡΠ°ΡΡΡΠΈΡΡΠ²Π°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π² Π²ΠΈΠ΄Π΅ ΡΠΈΡΠ»Π° ΡΠΈΠΏΠ° double; Π² ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΡ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π½Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Invalid.
ΠΡ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ ΡΡΡ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ, ΠΏΠΎΠΊΠ° Π½Π΅ Π·Π°ΠΊΠΎΠ½ΡΠ°ΡΡΡ ΡΠ΅ΡΠΌΡ. ΠΡΠΎ Π΄Π°ΡΡ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ Π²ΡΡΠΈΡΠ°Π½ΠΈΡ ΠΎΠ±Π»Π°Π΄Π°ΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΠΌ Β«Π°ΡΡΠΎΡΠΈΠ°ΡΠΈΠ²Π½ΠΎΡΡΠΈ ΡΠ»Π΅Π²Π°Β» (leftβassociative), ΡΠΎ Π΅ΡΡΡ Β«1β2β3Β» ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ Β«(1β2)β3Β», Π° Π½Π΅ Β«1β(2β3)Β».
01 QVariant Cell::evalTerm(const QString &str, int &pos) const
02 {
03 QVariant result = evalFactor(str, pos);
04 while (str[pos] != QChar::Null) {
05 QChar op = str[pos];
06 if (op != '*' && op != '/')
07 return result;
08 ++pos;
09 QVariant factor = evalFactor(str, pos);
10 if (result.type() == QVariant::Double &&
11 factor.type() == QVariant::Double) {
12 if (op == '*') {
13 result = result.toDouble() * factor.toDouble();
14 } else {
15 if (factor.toDouble() == 0.0) {
16 result = Invalid;
17 } else {
18 result = result.toDouble() / factor.toDouble();
19 }
20 }
21 } else {
22 result = Invalid;
23 }
24 }
25 return result;
26 }
Π€ΡΠ½ΠΊΡΠΈΡ evalTerm() ΠΎΡΠ΅Π½Ρ Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ evalExpression(), Π½ΠΎ, Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ, ΠΎΠ½Π° ΠΈΠΌΠ΅Π΅Ρ Π΄Π΅Π»ΠΎ Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠΌΠΈ ΡΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ Π΄Π΅Π»Π΅Π½ΠΈΡ. Π ΡΡΠ½ΠΊΡΠΈΠΈ evalTerm() Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΠΈΡΡΠ²Π°ΡΡ ΠΎΠ΄Π½Ρ ΡΠΎΠ½ΠΊΠΎΡΡΡ, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ: Π½Π΅Π»ΡΠ·Ρ Π΄ΠΎΠΏΡΡΠΊΠ°ΡΡ Π΄Π΅Π»Π΅Π½ΠΈΡ Π½Π° Π½ΡΠ»Ρ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ ΠΎΡΠΈΠ±ΠΊΠ΅ Π½Π° Π½Π΅ΠΊΠΎΡΠΎΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°Ρ . Π₯ΠΎΡΡ Π½Π΅ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ ΡΠ°Π²Π΅Π½ΡΡΠ²ΠΎ ΡΠΈΡΠ΅Π» Ρ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΡΠΎΡΠΊΠΎΠΉ ΠΈΠ·-Π·Π° ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΠΊΡΡΠ³Π»Π΅Π½ΠΈΡ, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΏΠΎΠΊΠΎΠΉΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Π½Π° ΡΠ°Π²Π΅Π½ΡΡΠ²ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ 0.0 Π΄Π»Ρ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΡ Π΄Π΅Π»Π΅Π½ΠΈΡ Π½Π° Π½ΡΠ»Ρ.
01 QVariant Cell::evalFactor(const QString &str, int &pos) const
02 {
03 QVariant result;
04 bool negative = false;
05 if (str[pos] == '-') {
06 negative = true;
07 ++pos;
08 }
09 if (str[pos] == '(') {
10 ++pos;
11 result = evalExpression(str, pos);
12 if (str[pos] != ')')
13 result = Invalid;
14 ++pos;
15 } else {
16 QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
17 QString token;
18 while (str[pos].isLetterOrNumber() || str[pos] == '.') {
19 token += str[pos];
20 ++pos;
21 }
22 if (regExp.exactMatch(token)) {
23 int column = token[0].toUpper().unicode() - 'A';
24 int row = token.mid(1).toInt() - 1;
25 Cell *c = static_cast<Cell *>(tableWidget()->item(row, column));
26 if (c) {
27 result = c->value();
28 } else {
29 result = 0.0;
30 }
31 } else {
32 bool ok;
33 result = token.toDouble(&ok);
34 if (!ok)
35 result = Invalid;
36 }
37 }
38 if (negative) {
39 if (result.type() == QVariant::Double) {
40 result = -result.toDouble();
41 } else {
42 result = Invalid;
43 }
44 }
45 return result;
46 }
Π€ΡΠ½ΠΊΡΠΈΡ evalFactor() Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ»ΠΎΠΆΠ½Π΅Π΅, ΡΠ΅ΠΌ evalExpression() ΠΈ evalTerm(). ΠΡ Π½Π°ΡΠΈΠ½Π°Π΅ΠΌ Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ, Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈ ΡΠ°ΠΊΡΠΎΡ ΠΎΡΡΠΈΡΠ°ΡΠ΅Π»ΡΠ½ΡΠΌ. ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π½Π°Π»ΠΈΡΠΈΠ΅ ΠΎΡΠΊΡΡΡΠΎΠΉ ΡΠΊΠΎΠ±ΠΊΠΈ. ΠΡΠ»ΠΈ ΠΎΠ½Π° ΠΈΠΌΠ΅Π΅ΡΡΡ, ΠΌΡ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π²Π½ΡΡΡΠΈ ΡΠΊΠΎΠ±ΠΎΠΊ ΠΊΠ°ΠΊ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, Π²ΡΠ·ΡΠ²Π°Ρ evalExpression(). ΠΡΠΈ Π°Π½Π°Π»ΠΈΠ·Π΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΡΠΊΠΎΠ±ΠΊΠ°Ρ evalExpression() Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ evalTerm(), ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ evalFactor(), ΠΊΠΎΡΠΎΡΠ°Ρ Π²Π½ΠΎΠ²Ρ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ evalExpression(). ΠΠΌΠ΅Π½Π½ΠΎ Π² ΡΡΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΠΊΡΡΡΠΈΡ ΠΏΡΠΈ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΌ Π°Π½Π°Π»ΠΈΠ·Π΅.
ΠΡΠ»ΠΈ ΡΠ°ΠΊΡΠΎΡΠΎΠΌ Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, ΠΌΡ Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΡΡ Π»Π΅ΠΊΡΠ΅ΠΌΡ (token), ΠΈ ΠΎΠ½Π° Π΄ΠΎΠ»ΠΆΠ½Π° Π·Π°Π΄Π°Π²Π°ΡΡ ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΠΉΠΊΠΈ ΠΈΠ»ΠΈ Π±ΡΡΡ ΡΠΈΡΠ»ΠΎΠΌ. ΠΡΠ»ΠΈ ΡΡΠ° Π»Π΅ΠΊΡΠ΅ΠΌΠ° ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΡΠ΅Ρ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠΌΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ QRegExp, ΠΌΡ ΡΡΠΈΡΠ°Π΅ΠΌ, ΡΡΠΎ ΠΎΠ½Π° ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΡΠ»ΠΊΠΎΠΉ Π½Π° ΡΡΠ΅ΠΉΠΊΡ, ΠΈ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ value() Π΄Π»Ρ ΡΡΠΎΠΉ ΡΡΠ΅ΠΉΠΊΠΈ. Π―ΡΠ΅ΠΉΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ ΡΠ°ΡΠΏΠΎΠ»Π°Π³Π°ΡΡΡΡ Π² Π»ΡΠ±ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ Π² ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΡΠ°Π±Π»ΠΈΡΠ΅, ΠΈ ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ ΡΡΡΠ»Π°ΡΡΡΡ Π½Π° Π΄ΡΡΠ³ΠΈΠ΅ ΡΡΠ΅ΠΉΠΊΠΈ. Π’Π°ΠΊΠ°Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡ Π½Π΅ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΈ ΠΏΡΠΎΡΡΠΎ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌ Π²ΡΠ·ΠΎΠ²Π°ΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ value() ΠΈ ΠΊ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΌΡ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΌΡ Π°Π½Π°Π»ΠΈΠ·Ρ ΡΡΠ΅Π΅ΠΊ Ρ ΠΏΡΠΈΠ·Π½Π°ΠΊΠΎΠΌ Β«dirtyΒ» (Β«Π³ΡΡΠ·Π½ΡΠΉΒ») Π΄Π»Ρ ΠΏΠ΅ΡΠ΅ΡΠ°ΡΡΠ΅ΡΠ° Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π²ΡΠ΅Ρ Π·Π°Π²ΠΈΡΠΈΠΌΡΡ ΡΡΠ΅Π΅ΠΊ. ΠΡΠ»ΠΈ Π»Π΅ΠΊΡΠ΅ΠΌΠ° Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΡΠ»ΠΊΠΎΠΉ Π½Π° ΡΡΠ΅ΠΉΠΊΡ, ΠΌΡ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΠΌ Π΅Π΅ ΠΊΠ°ΠΊ ΡΠΈΡΠ»ΠΎ.
Π§ΡΠΎ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ, Π΅ΡΠ»ΠΈ ΡΡΠ΅ΠΉΠΊΠ° A1 ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΠΎΡΠΌΡΠ»Ρ Β«=A1Β»? ΠΠ»ΠΈ Π΅ΡΠ»ΠΈ ΡΡΠ΅ΠΉΠΊΠ° A1 ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Β«=A2Β», Π° ΡΡΠ΅ΠΉΠΊΠ° A2 ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Β«=A1Β»? Π₯ΠΎΡΡ Π½Π°ΠΌΠΈ Π½Π΅ Π½Π°ΠΏΠΈΡΠ°Π½ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ Π΄Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΈΠΊΠ»ΠΎΠ² Π² ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΡΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡΡ , ΠΏΠ°ΡΡΠ΅Ρ ΠΏΡΠ΅ΠΊΡΠ°ΡΠ½ΠΎ ΡΠΏΡΠ°Π²ΠΈΡΡΡ Ρ ΡΡΠΎΠΉ ΡΠΈΡΡΠ°ΡΠΈΠ΅ΠΉ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠΈΡ Π½Π΅Π΄ΠΎΠΏΡΡΡΠΈΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡΠΈΠΏΠ° QVariant. ΠΡΠΎ Π΄Π°ΡΡ Π½ΡΠΆΠ½ΡΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠ»Π°ΠΆΠΎΠΊ cacheIsDirty Π½Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ false ΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ cachedValue Π½Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Invalid Π² ΡΡΠ½ΠΊΡΠΈΠΈ value() ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ evalExpression(). ΠΡΠ»ΠΈ evalExpression() ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΠΎ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ value() Π΄Π»Ρ ΡΠΎΠΉ ΠΆΠ΅ ΡΡΠ΅ΠΉΠΊΠΈ, ΠΎΠ½Π° Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Invalid, ΠΈ ΡΠΎΠ³Π΄Π° Π²ΡΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Invalid.