Skip to content

Commit b63e5a1

Browse files
committed
Issue #18: Setting for disabling lazy evaluation of multiplication
see especially MainTestCase#testGithub18() test case
1 parent bc3e6df commit b63e5a1

File tree

13 files changed

+454
-357
lines changed

13 files changed

+454
-357
lines changed

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/basic/Config.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,9 @@ public class Config {
162162
public static boolean isFileSystemEnabled(EvalEngine engine) {
163163
return FILESYSTEM_ENABLED || engine.isFileSystemEnabled();
164164
}
165+
166+
/**
167+
* If <code>true</code> the <code>*</code> operator must be written for a <code>Times()</code> expression.
168+
*/
169+
public static boolean EXPLICIT_TIMES_OPERATOR = false;
165170
}

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/parser/ExprParser.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,9 @@ private IExpr getFactor() throws SyntaxError {
392392
}
393393
getNextToken();
394394
if (fToken == TT_PRECEDENCE_OPEN) {
395-
return getTimes(temp);
395+
if (!Config.EXPLICIT_TIMES_OPERATOR) {
396+
return getTimes(temp);
397+
}
396398
}
397399
if (fToken == TT_ARGUMENTS_OPEN) {
398400
return getFunctionArguments(temp);
@@ -1068,15 +1070,15 @@ private IExpr parseExpression(IExpr lhs, final int min_precedence) {
10681070
// '\n') {
10691071
// return lhs;
10701072
// }
1071-
// lazy evaluation of multiplication
1072-
oper = fFactory.get("Times");
1073-
if (oper.getPrecedence() >= min_precedence) {
1074-
rhs = parseLookaheadOperator(oper.getPrecedence());
1075-
lhs = F.$(F.$s(oper.getFunctionName()), lhs, rhs);
1076-
// lhs =
1077-
// fFactory.createFunction(fFactory.createSymbol(oper.getFunctionName()),
1078-
// lhs, rhs);
1079-
continue;
1073+
1074+
if (!Config.EXPLICIT_TIMES_OPERATOR) {
1075+
// lazy evaluation of multiplication
1076+
oper = fFactory.get("Times");
1077+
if (oper.getPrecedence() >= min_precedence) {
1078+
rhs = parseLookaheadOperator(oper.getPrecedence());
1079+
lhs = F.$(F.$s(oper.getFunctionName()), lhs, rhs);
1080+
continue;
1081+
}
10801082
}
10811083
} else {
10821084
if (fToken == TT_DERIVATIVE) {
@@ -1150,18 +1152,17 @@ private IExpr parseLookaheadOperator(final int min_precedence) {
11501152
}
11511153
if ((fToken == TT_LIST_OPEN) || (fToken == TT_PRECEDENCE_OPEN) || (fToken == TT_IDENTIFIER)
11521154
|| (fToken == TT_STRING) || (fToken == TT_DIGIT) || (fToken == TT_SLOT)) {
1153-
// if (fPackageMode && fRecursionDepth < 1) {
1154-
// return rhs;
1155-
// }
1156-
// lazy evaluation of multiplication
1157-
InfixExprOperator timesOperator = (InfixExprOperator) fFactory.get("Times");
1158-
if (timesOperator.getPrecedence() > min_precedence) {
1159-
rhs = parseExpression(rhs, timesOperator.getPrecedence());
1160-
continue;
1161-
} else if ((timesOperator.getPrecedence() == min_precedence)
1162-
&& (timesOperator.getGrouping() == InfixExprOperator.RIGHT_ASSOCIATIVE)) {
1163-
rhs = parseExpression(rhs, timesOperator.getPrecedence());
1164-
continue;
1155+
if (!Config.EXPLICIT_TIMES_OPERATOR) {
1156+
// lazy evaluation of multiplication
1157+
InfixExprOperator timesOperator = (InfixExprOperator) fFactory.get("Times");
1158+
if (timesOperator.getPrecedence() > min_precedence) {
1159+
rhs = parseExpression(rhs, timesOperator.getPrecedence());
1160+
continue;
1161+
} else if ((timesOperator.getPrecedence() == min_precedence)
1162+
&& (timesOperator.getGrouping() == InfixExprOperator.RIGHT_ASSOCIATIVE)) {
1163+
rhs = parseExpression(rhs, timesOperator.getPrecedence());
1164+
continue;
1165+
}
11651166
}
11661167
} else {
11671168
if (fToken == TT_DERIVATIVE) {

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/parser/ExprScanner.java

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.HashMap;
1919
import java.util.List;
2020

21+
import org.matheclipse.core.basic.Config;
2122
import org.matheclipse.parser.client.Characters;
2223
import org.matheclipse.parser.client.SyntaxError;
2324

@@ -162,7 +163,7 @@ public class ExprScanner {
162163
* Token type: pattern placeholder '_'
163164
*/
164165
final static public int TT_BLANK = 142;
165-
166+
166167
final static public int TT_BLANK_BLANK = 143;
167168

168169
final static public int TT_BLANK_BLANK_BLANK = 144;
@@ -689,38 +690,40 @@ protected Object[] getNumberString() {
689690
dFlag = fCurrentChar;
690691
}
691692
getChar();
692-
if (firstCh == '0') {
693-
switch (fCurrentChar) {
694-
case 'b': // binary format
695-
numFormat = 2;
696-
startPosition = fCurrentPosition;
697-
getChar();
698-
break;
699-
case 'B': // binary format
700-
numFormat = 2;
701-
startPosition = fCurrentPosition;
702-
getChar();
703-
break;
704-
case 'o': // octal format
705-
numFormat = 8;
706-
startPosition = fCurrentPosition;
707-
getChar();
708-
break;
709-
case 'O': // octal format
710-
numFormat = 8;
711-
startPosition = fCurrentPosition;
712-
getChar();
713-
break;
714-
case 'x': // hexadecimal format
715-
numFormat = 16;
716-
startPosition = fCurrentPosition;
717-
getChar();
718-
break;
719-
case 'X': // hexadecimal format
720-
numFormat = 16;
721-
startPosition = fCurrentPosition;
722-
getChar();
723-
break;
693+
if (Config.EXPLICIT_TIMES_OPERATOR) {
694+
if (firstCh == '0') {
695+
switch (fCurrentChar) {
696+
case 'b': // binary format
697+
numFormat = 2;
698+
startPosition = fCurrentPosition;
699+
getChar();
700+
break;
701+
case 'B': // binary format
702+
numFormat = 2;
703+
startPosition = fCurrentPosition;
704+
getChar();
705+
break;
706+
case 'o': // octal format
707+
numFormat = 8;
708+
startPosition = fCurrentPosition;
709+
getChar();
710+
break;
711+
case 'O': // octal format
712+
numFormat = 8;
713+
startPosition = fCurrentPosition;
714+
getChar();
715+
break;
716+
case 'x': // hexadecimal format
717+
numFormat = 16;
718+
startPosition = fCurrentPosition;
719+
getChar();
720+
break;
721+
case 'X': // hexadecimal format
722+
numFormat = 16;
723+
startPosition = fCurrentPosition;
724+
getChar();
725+
break;
726+
}
724727
}
725728
}
726729

@@ -744,14 +747,8 @@ protected Object[] getNumberString() {
744747
if ((fCurrentChar == '.') && (dFlag != ' ')) {
745748
break;
746749
}
747-
// if ((dFlag == 'E') || (dFlag == 'e')) {
748-
// break;
749-
// }
750750
dFlag = fCurrentChar;
751751
getChar();
752-
// if ((ch == '-') || (ch == '+')) {
753-
// getChar();
754-
// }
755752
} else {
756753
getChar();
757754
}
@@ -760,16 +757,20 @@ protected Object[] getNumberString() {
760757
numFormat = -1;
761758
}
762759
}
763-
if (numFormat < 0) {
764-
if ((fCurrentChar == 'E') || (fCurrentChar == 'e')) {
760+
761+
if ((fCurrentChar == 'E') || (fCurrentChar == 'e')) {
762+
if (Config.EXPLICIT_TIMES_OPERATOR) {
763+
numFormat = -1;
765764
getChar();
766765
if ((fCurrentChar == '+') || (fCurrentChar == '-')) {
767766
getChar();
768767
}
769768
while (((fCurrentChar >= '0') && (fCurrentChar <= '9'))) {
770769
getChar();
771770
}
772-
} else {
771+
}
772+
} else {
773+
if (numFormat < 0) {
773774
if (fCurrentChar == '*') {
774775
int lastPosition = fCurrentPosition;
775776
getChar();
@@ -791,6 +792,7 @@ protected Object[] getNumberString() {
791792
}
792793
}
793794
}
795+
794796
// }
795797
int endPosition = fCurrentPosition--;
796798
result[0] = fInputString.substring(startPosition, --endPosition);

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/parser/client/Parser.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,9 @@ private ASTNode getFactor() throws SyntaxError {
226226
}
227227
getNextToken();
228228
if (fToken == TT_PRECEDENCE_OPEN) {
229-
return getTimes(temp);
229+
if (!Config.EXPLICIT_TIMES_OPERATOR) {
230+
return getTimes(temp);
231+
}
230232
}
231233
if (fToken == TT_ARGUMENTS_OPEN) {
232234
return getFunctionArguments(temp);
@@ -801,12 +803,14 @@ private ASTNode parseExpression(ASTNode lhs, final int min_precedence) {
801803
if ((fToken == TT_LIST_OPEN) || (fToken == TT_PRECEDENCE_OPEN) || (fToken == TT_IDENTIFIER)
802804
|| (fToken == TT_STRING) || (fToken == TT_DIGIT) || (fToken == TT_SLOT)
803805
|| (fToken == TT_SLOTSEQUENCE)) {
804-
// lazy evaluation of multiplication
805-
oper = fFactory.get("Times");
806-
if (oper.getPrecedence() >= min_precedence) {
807-
rhs = parseLookaheadOperator(oper.getPrecedence());
808-
lhs = fFactory.createFunction(fFactory.createSymbol(oper.getFunctionName()), lhs, rhs);
809-
continue;
806+
if (!Config.EXPLICIT_TIMES_OPERATOR) {
807+
// lazy evaluation of multiplication
808+
oper = fFactory.get("Times");
809+
if (oper.getPrecedence() >= min_precedence) {
810+
rhs = parseLookaheadOperator(oper.getPrecedence());
811+
lhs = fFactory.createFunction(fFactory.createSymbol(oper.getFunctionName()), lhs, rhs);
812+
continue;
813+
}
810814
}
811815
} else {
812816
if (fToken == TT_DERIVATIVE) {
@@ -881,15 +885,17 @@ private ASTNode parseLookaheadOperator(final int min_precedence) {
881885
}
882886
if ((fToken == TT_LIST_OPEN) || (fToken == TT_PRECEDENCE_OPEN) || (fToken == TT_IDENTIFIER)
883887
|| (fToken == TT_STRING) || (fToken == TT_DIGIT) || (fToken == TT_SLOT)) {
884-
// lazy evaluation of multiplication
885-
InfixOperator timesOperator = (InfixOperator) fFactory.get("Times");
886-
if (timesOperator.getPrecedence() > min_precedence) {
887-
rhs = parseExpression(rhs, timesOperator.getPrecedence());
888-
continue;
889-
} else if ((timesOperator.getPrecedence() == min_precedence)
890-
&& (timesOperator.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE)) {
891-
rhs = parseExpression(rhs, timesOperator.getPrecedence());
892-
continue;
888+
if (!Config.EXPLICIT_TIMES_OPERATOR) {
889+
// lazy evaluation of multiplication
890+
InfixOperator timesOperator = (InfixOperator) fFactory.get("Times");
891+
if (timesOperator.getPrecedence() > min_precedence) {
892+
rhs = parseExpression(rhs, timesOperator.getPrecedence());
893+
continue;
894+
} else if ((timesOperator.getPrecedence() == min_precedence)
895+
&& (timesOperator.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE)) {
896+
rhs = parseExpression(rhs, timesOperator.getPrecedence());
897+
continue;
898+
}
893899
}
894900
} else {
895901
if (fToken == TT_DERIVATIVE) {

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/parser/client/Scanner.java

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.List;
2020
import java.util.Stack;
2121

22+
import org.matheclipse.core.basic.Config;
2223
import org.matheclipse.parser.client.ast.IParserFactory;
2324
import org.matheclipse.parser.client.operator.Operator;
2425

@@ -549,39 +550,41 @@ protected Object[] getNumberString() {
549550
dFlag = fCurrentChar;
550551
}
551552
getChar();
552-
if (firstCh == '0') {
553-
switch (fCurrentChar) {
554-
case 'b': // binary format
555-
numFormat = 2;
556-
startPosition = fCurrentPosition;
557-
getChar();
558-
break;
559-
case 'B': // binary format
560-
numFormat = 2;
561-
startPosition = fCurrentPosition;
562-
getChar();
563-
break;
564-
case 'o': // octal format
565-
numFormat = 8;
566-
startPosition = fCurrentPosition;
567-
getChar();
568-
break;
569-
case 'O': // octal format
570-
numFormat = 8;
571-
startPosition = fCurrentPosition;
572-
getChar();
573-
break;
574-
case 'x': // hexadecimal format
575-
numFormat = 16;
576-
startPosition = fCurrentPosition;
577-
getChar();
578-
break;
579-
case 'X': // hexadecimal format
580-
numFormat = 16;
581-
startPosition = fCurrentPosition;
582-
getChar();
583-
break;
584-
default:
553+
if (Config.EXPLICIT_TIMES_OPERATOR) {
554+
if (firstCh == '0') {
555+
switch (fCurrentChar) {
556+
case 'b': // binary format
557+
numFormat = 2;
558+
startPosition = fCurrentPosition;
559+
getChar();
560+
break;
561+
case 'B': // binary format
562+
numFormat = 2;
563+
startPosition = fCurrentPosition;
564+
getChar();
565+
break;
566+
case 'o': // octal format
567+
numFormat = 8;
568+
startPosition = fCurrentPosition;
569+
getChar();
570+
break;
571+
case 'O': // octal format
572+
numFormat = 8;
573+
startPosition = fCurrentPosition;
574+
getChar();
575+
break;
576+
case 'x': // hexadecimal format
577+
numFormat = 16;
578+
startPosition = fCurrentPosition;
579+
getChar();
580+
break;
581+
case 'X': // hexadecimal format
582+
numFormat = 16;
583+
startPosition = fCurrentPosition;
584+
getChar();
585+
break;
586+
default:
587+
}
585588
}
586589
}
587590

@@ -614,16 +617,19 @@ protected Object[] getNumberString() {
614617
numFormat = -1;
615618
}
616619
}
617-
if (numFormat < 0) {
618-
if ((fCurrentChar == 'E') || (fCurrentChar == 'e')) {
620+
621+
if ((fCurrentChar == 'E') || (fCurrentChar == 'e')) {
622+
if (Config.EXPLICIT_TIMES_OPERATOR) {
619623
getChar();
620624
if ((fCurrentChar == '+') || (fCurrentChar == '-')) {
621625
getChar();
622626
}
623627
while ((fCurrentChar >= '0') && (fCurrentChar <= '9')) {
624628
getChar();
625629
}
626-
} else {
630+
}
631+
} else {
632+
if (numFormat < 0) {
627633
if (fCurrentChar == '*') {
628634
int lastPosition = fCurrentPosition;
629635
getChar();
@@ -645,6 +651,7 @@ protected Object[] getNumberString() {
645651
}
646652
}
647653
}
654+
648655
int endPosition = fCurrentPosition--;
649656
result[0] = fInputString.substring(startPosition, --endPosition);
650657
result[1] = Integer.valueOf(numFormat);

0 commit comments

Comments
 (0)