use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.
the class Parser method parsePackage.
/**
* Parse a package.
*
* @param expression
* @return
* @throws SyntaxError
*/
public List<ASTNode> parsePackage(final String expression) throws SyntaxError {
initialize(expression);
while (fToken == TT_NEWLINE) {
getNextToken();
}
ASTNode temp = parseExpression();
fNodeList.add(temp);
while (fToken != TT_EOF) {
if (fToken == TT_PRECEDENCE_CLOSE) {
throwSyntaxError("Too many closing ')'; End-of-file not reached.");
}
if (fToken == TT_LIST_CLOSE) {
throwSyntaxError("Too many closing '}'; End-of-file not reached.");
}
if (fToken == TT_ARGUMENTS_CLOSE) {
throwSyntaxError("Too many closing ']'; End-of-file not reached.");
}
while (fToken == TT_NEWLINE) {
getNextToken();
}
if (fToken == TT_EOF) {
return fNodeList;
}
temp = parseExpression();
fNodeList.add(temp);
}
return fNodeList;
}
use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.
the class DoubleEvaluator method derivative.
/**
*
* TODO: add more derivation rules
*
* @param node
* @param var
* @return
*/
public ASTNode derivative(final ASTNode node, SymbolNode var) {
if (node.isFree(var)) {
return new DoubleNode(0.0);
}
if (node instanceof FunctionNode) {
FunctionNode f = (FunctionNode) node;
if (f.size() > 1 && f.getNode(0) instanceof SymbolNode) {
SymbolNode head = (SymbolNode) f.getNode(0);
if (f.size() == 2) {
ASTNode arg1Derived = derivative(f.getNode(1), var);
if (isSymbol(head, "Exp")) {
FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Exp"));
fun.add(f.getNode(1));
return getDerivativeResult(arg1Derived, fun);
}
if (isSymbol(head, "Cos")) {
FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Times"));
fun.add(new DoubleNode(-1.0));
fun.add(new FunctionNode(fASTFactory.createSymbol("Cos"), f.getNode(1)));
return getDerivativeResult(arg1Derived, fun);
}
if (isSymbol(head, "Sin")) {
FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Cos"));
fun.add(f.getNode(1));
return getDerivativeResult(arg1Derived, fun);
}
} else if (f.size() == 3 && isSymbol(head, "Power")) {
if (f.get(2).isFree(var)) {
// derive x^r
ASTNode arg1Derived = derivative(f.getNode(1), var);
// (r-1)
FunctionNode exponent = fASTFactory.createFunction(fASTFactory.createSymbol("Plus"), new DoubleNode(-1.0), f.get(2));
// r*x^(r-1)
FunctionNode fun = fASTFactory.createFunction(fASTFactory.createSymbol("Times"), f.get(2), fASTFactory.createFunction(fASTFactory.createSymbol("Power"), f.get(1), exponent));
return getDerivativeResult(arg1Derived, fun);
}
if (f.get(1).isFree(var)) {
// derive a^x
ASTNode arg2Derived = derivative(f.getNode(2), var);
// log(a) * a^x
FunctionNode fun = fASTFactory.createFunction(fASTFactory.createSymbol("Times"), fASTFactory.createFunction(fASTFactory.createSymbol("Log"), f.get(1)), f);
return getDerivativeResult(arg2Derived, fun);
}
} else {
if (isSymbol(head, "Plus")) {
FunctionNode result = new FunctionNode(f.getNode(0));
for (int i = 1; i < f.size(); i++) {
ASTNode deriv = derivative(f.getNode(i), var);
if (!deriv.equals(new DoubleNode(0.0))) {
result.add(deriv);
}
}
return result;
}
if (isSymbol(head, "Times")) {
FunctionNode plusResult = new FunctionNode(fASTFactory.createSymbol("Plus"));
for (int i = 1; i < f.size(); i++) {
FunctionNode timesResult = new FunctionNode(f.getNode(0));
boolean valid = true;
for (int j = 1; j < f.size(); j++) {
if (j == i) {
ASTNode deriv = derivative(f.getNode(j), var);
if (deriv.equals(new DoubleNode(0.0))) {
valid = false;
} else {
timesResult.add(deriv);
}
} else {
timesResult.add(f.getNode(j));
}
}
if (valid) {
plusResult.add(timesResult);
}
}
return plusResult;
}
}
}
return new FunctionNode(new SymbolNode("D"), node, var);
// return evaluateFunction((FunctionNode) node);
}
if (node instanceof SymbolNode) {
if (isSymbol((SymbolNode) node, var)) {
return new DoubleNode(1.0);
}
IDoubleValue v = fVariableMap.get(node.toString());
if (v != null) {
return new DoubleNode(0.0);
}
Double dbl = SYMBOL_DOUBLE_MAP.get(node.toString());
if (dbl != null) {
return new DoubleNode(0.0);
}
return new DoubleNode(0.0);
} else if (node instanceof NumberNode) {
return new DoubleNode(0.0);
}
throw new ArithmeticMathException("EvalDouble#evaluate(ASTNode) not possible for: " + node.toString());
}
use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.
the class Parser method getFactor.
private ASTNode getFactor() throws SyntaxError {
ASTNode temp;
if (fToken == TT_PRECEDENCE_OPEN) {
fRecursionDepth++;
try {
getNextToken();
temp = parseExpression();
if (fToken != TT_PRECEDENCE_CLOSE) {
throwSyntaxError("\')\' expected.");
}
} finally {
fRecursionDepth--;
}
getNextToken();
if (fToken == TT_PRECEDENCE_OPEN) {
return getTimes(temp);
}
if (fToken == TT_ARGUMENTS_OPEN) {
return getFunctionArguments(temp);
}
return temp;
} else if (fToken == TT_LIST_OPEN) {
return getList();
} else if (fToken == TT_IDENTIFIER) {
final SymbolNode symbol = getSymbol();
if (fToken == TT_BLANK) {
// read '_'
if (isWhitespace()) {
temp = fFactory.createPattern(symbol, null);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(symbol, check);
} else {
temp = fFactory.createPattern(symbol, null);
}
}
} else if (fToken == TT_BLANK_BLANK) {
// read '__'
if (isWhitespace()) {
temp = fFactory.createPattern2(symbol, null);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern2(symbol, check);
} else {
temp = fFactory.createPattern2(symbol, null);
}
}
} else if (fToken == TT_BLANK_BLANK_BLANK) {
// read '___'
if (isWhitespace()) {
temp = fFactory.createPattern3(symbol, null);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern3(symbol, check);
} else {
temp = fFactory.createPattern3(symbol, null);
}
}
} else if (fToken == TT_BLANK_OPTIONAL) {
// read '_.'
if (isWhitespace()) {
temp = fFactory.createPattern(symbol, null, true);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(symbol, check, true);
} else {
temp = fFactory.createPattern(symbol, null, true);
}
}
} else if (fToken == TT_BLANK_COLON) {
// read '_:'
getNextToken();
ASTNode defaultValue = parseExpression();
temp = fFactory.createPattern(symbol, null, defaultValue);
} else {
temp = symbol;
}
return parseArguments(temp);
} else if (fToken == TT_BLANK) {
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern(null, null);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(null, check);
} else {
temp = fFactory.createPattern(null, null);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_BLANK) {
// read '__'
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern2(null, null);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern2(null, check);
} else {
temp = fFactory.createPattern2(null, null);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_BLANK_BLANK) {
// read '___'
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern3(null, null);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern3(null, check);
} else {
temp = fFactory.createPattern3(null, null);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_OPTIONAL) {
// read '_.'
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern(null, null, true);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(null, check, true);
} else {
temp = fFactory.createPattern(null, null, true);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_COLON) {
// read '_:'
getNextToken();
ASTNode defaultValue = parseExpression();
temp = fFactory.createPattern(null, null, defaultValue);
return parseArguments(temp);
} else if (fToken == TT_DIGIT) {
return getNumber(false);
} else if (fToken == TT_STRING) {
return getString();
} else if (fToken == TT_PERCENT) {
final FunctionNode out = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Out));
int countPercent = 1;
getNextToken();
if (fToken == TT_DIGIT) {
countPercent = getIntegerNumber();
out.add(fFactory.createInteger(countPercent));
return out;
}
while (fToken == TT_PERCENT) {
countPercent++;
getNextToken();
}
out.add(fFactory.createInteger(-countPercent));
return parseArguments(out);
} else if (fToken == TT_SLOT) {
getNextToken();
final FunctionNode slot = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Slot));
if (fToken == TT_DIGIT) {
slot.add(getNumber(false));
} else {
slot.add(fFactory.createInteger(1));
}
return parseArguments(slot);
} else if (fToken == TT_SLOTSEQUENCE) {
getNextToken();
final FunctionNode slotSequencce = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.SlotSequence));
if (fToken == TT_DIGIT) {
slotSequencce.add(getNumber(false));
} else {
slotSequencce.add(fFactory.createInteger(1));
}
return parseArguments(slotSequencce);
}
switch(fToken) {
case TT_PRECEDENCE_CLOSE:
throwSyntaxError("Too much closing ) in factor.");
break;
case TT_LIST_CLOSE:
throwSyntaxError("Too much closing } in factor.");
break;
case TT_ARGUMENTS_CLOSE:
throwSyntaxError("Too much closing ] in factor.");
break;
}
throwSyntaxError("Error in factor at character: '" + fCurrentChar + "' (" + fToken + ")");
return null;
}
use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.
the class Parser method parseLookaheadOperator.
private ASTNode parseLookaheadOperator(final int min_precedence) {
ASTNode rhs = parsePrimary();
while (true) {
final int lookahead = fToken;
if (fToken == TT_NEWLINE) {
return rhs;
}
if ((fToken == TT_LIST_OPEN) || (fToken == TT_PRECEDENCE_OPEN) || (fToken == TT_IDENTIFIER) || (fToken == TT_STRING) || (fToken == TT_DIGIT) || (fToken == TT_SLOT)) {
// lazy evaluation of multiplication
InfixOperator timesOperator = (InfixOperator) fFactory.get("Times");
if (timesOperator.getPrecedence() > min_precedence) {
rhs = parseExpression(rhs, timesOperator.getPrecedence());
continue;
} else if ((timesOperator.getPrecedence() == min_precedence) && (timesOperator.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE)) {
rhs = parseExpression(rhs, timesOperator.getPrecedence());
continue;
}
} else {
if (fToken == TT_DERIVATIVE) {
rhs = parseDerivative(rhs);
}
if (lookahead != TT_OPERATOR) {
break;
}
InfixOperator infixOperator = determineBinaryOperator();
if (infixOperator != null) {
if (infixOperator.getPrecedence() > min_precedence || ((infixOperator.getPrecedence() == min_precedence) && (infixOperator.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE))) {
if (";".equals(infixOperator.getOperatorString())) {
if (fPackageMode && fRecursionDepth < 1) {
return infixOperator.createFunction(fFactory, rhs, fFactory.createSymbol("Null"));
}
}
rhs = parseExpression(rhs, infixOperator.getPrecedence());
continue;
}
} else {
PostfixOperator postfixOperator = determinePostfixOperator();
if (postfixOperator != null) {
if (postfixOperator.getPrecedence() >= min_precedence) {
getNextToken();
rhs = postfixOperator.createFunction(fFactory, rhs);
continue;
}
}
}
}
break;
}
return rhs;
}
use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.
the class Parser method parsePrimary.
private ASTNode parsePrimary() {
if (fToken == TT_OPERATOR) {
if (";;".equals(fOperatorString)) {
FunctionNode function = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Span));
function.add(fFactory.createInteger(1));
getNextToken();
if (fToken == TT_COMMA || fToken == TT_ARGUMENTS_CLOSE || fToken == TT_PRECEDENCE_CLOSE) {
function.add(fFactory.createSymbol(IConstantOperators.All));
return function;
}
function.add(parsePrimary());
if (fToken == TT_OPERATOR && ";;".equals(fOperatorString)) {
function.add(fFactory.createSymbol(IConstantOperators.All));
getNextToken();
}
return function;
}
if (".".equals(fOperatorString)) {
fCurrentChar = '.';
return getNumber(false);
}
final PrefixOperator prefixOperator = determinePrefixOperator();
if (prefixOperator != null) {
getNextToken();
final ASTNode temp = parseLookaheadOperator(prefixOperator.getPrecedence());
if ("PreMinus".equals(prefixOperator.getFunctionName()) && temp instanceof NumberNode) {
// special cases for negative numbers
((NumberNode) temp).toggleSign();
return temp;
}
return prefixOperator.createFunction(fFactory, temp);
}
throwSyntaxError("Operator: " + fOperatorString + " is no prefix operator.");
}
return getPart();
}
Aggregations