protected void processFunctionNameLexeme(Lexeme fName) { IToken next = pollNextInput(); if (next is ParenthesesToken) { int nArguments = properties.getFunctionArgumentsCount(fName.Value); ArgumentListNode arguments = parseArgumentList(next as ParenthesesToken, nArguments); if (arguments.Count != nArguments) { throw new ParseException( "Number of arguments given doesn't match function declaration for function: " + fName.Value); } FunctionApplyNode.FunctionBody funcDefinition = properties.getFunctionDefinition(fName.Value); FunctionApplyNode funcApplyNode = new FunctionApplyNode(arguments, funcDefinition, fName.Value); output.Enqueue(funcApplyNode); lastProcessedElement = funcApplyNode; } else if (next is Lexeme && (next as Lexeme).Type == Lexeme.LexemeType.LEFT_PAREN) { openedArgumentLists++; operatorStack.Push(fName); operatorStack.Push(next as Lexeme); lastProcessedElement = next as Lexeme; } else { throw new ParseException("Missing argument list for function call: " + fName.Value + " " + next.simpleRepresentation()); } }
protected SyntaxNode processFuncApplyToken(FunctionApplyToken func) { TokenList fNameNode = func.FunctionName; if (fNameNode.Count == 1) { if (fNameNode[0] is Lexeme) { // Samo naziv funkcije u fName, bez ikakvih eksponenata i sl. String functionName = (fNameNode[0] as Lexeme).Value; if (properties.IsFunctionName(functionName)) { int nArguments = properties.getFunctionArgumentsCount(functionName); ArgumentListNode arguments = parseArgumentList(func.Arguments, nArguments); if (arguments.Count != nArguments) { throw new ParseException( "Number of arguments given doesn't match function declaration for function: " + func.simpleRepresentation()); } FunctionApplyNode.FunctionBody definition = properties.getFunctionDefinition(functionName); return(new FunctionApplyNode(arguments, definition, functionName)); } } else if (fNameNode[0] is SuperscriptToken) { // eksponent u nazivu funkcije, npr. sin^-1(x) SuperscriptToken sup = fNameNode[0] as SuperscriptToken; if (sup.Base.Count == 1 && sup.Base[0] is TextRunToken) { String functionName = (sup.Base[0] as TextRunToken).Text; if (properties.IsFunctionName(functionName)) { int nArguments = properties.getFunctionArgumentsCount(functionName); ArgumentListNode arguments = parseArgumentList(func.Arguments, nArguments); if (arguments.Count != nArguments) { throw new ParseException( "Number of arguments given doesn't match function declaration for function: " + func.simpleRepresentation()); } TokenListParser exponentParser = new TokenListParser(properties); SyntaxNode exponentArgument = exponentParser.parse(sup.Argument); FunctionApplyNode.FunctionBody definition = properties.getFunctionDefinition(functionName); FunctionApplyNode exponentBase = new FunctionApplyNode(arguments, definition, functionName); return(new PowerNode(exponentBase, exponentArgument)); } } } } throw new ParseException("Can't process function name: " + func.simpleRepresentation()); }
protected SyntaxNode buildSyntaxTree(List <ISyntaxUnit> postfixForm) { Queue <ISyntaxUnit> inputQueue = new Queue <ISyntaxUnit>(postfixForm); Stack <SyntaxNode> operandStack = new Stack <SyntaxNode>(); while (inputQueue.Count > 0) { ISyntaxUnit input = inputQueue.Dequeue(); if (input is Lexeme) { Lexeme token = input as Lexeme; Lexeme.LexemeType ttype = token.Type; if (properties.IsVariable(token.Value)) { VariableIdentifierNode variable = new VariableIdentifierNode(token.Value); operandStack.Push(variable); } else if (properties.IsConstant(token.Value)) { double constantValue = properties.getConstantValue(token.Value); ConstantIdentifierNode constant = new ConstantIdentifierNode(token.Value, constantValue); operandStack.Push(constant); } else if (properties.IsFunctionName(token.Value)) { int nArguments = properties.getFunctionArgumentsCount(token.Value); FunctionApplyNode.FunctionBody funcBody = properties.getFunctionDefinition(token.Value); ArgumentListNode argumentList = new ArgumentListNode(); try { for (int i = 0; i < nArguments; i++) { argumentList.addArgument(operandStack.Pop()); } } catch (InvalidOperationException ex) { throw new ParseException("Not enough operands on operand stack for function call."); } FunctionApplyNode functionCall = new FunctionApplyNode(argumentList, funcBody, token.Value); operandStack.Push(functionCall); } else if (ttype == Lexeme.LexemeType.REAL_VALUE) { double value; if (!double.TryParse(token.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value)) { throw new ParseException("Couldn't parse literal value: " + token.Value); } LiteralNode literal = new LiteralNode(value); operandStack.Push(literal); } else if (ttype == Lexeme.LexemeType.OP_PLUS) { try { SyntaxNode right = operandStack.Pop(); SyntaxNode left = operandStack.Pop(); AdditionNode addition = new AdditionNode(left, right); operandStack.Push(addition); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand(s) for addition."); } } else if (ttype == Lexeme.LexemeType.OP_MINUS) { try { SyntaxNode right = operandStack.Pop(); SyntaxNode left = operandStack.Pop(); SubtractionNode subtraction = new SubtractionNode(left, right); operandStack.Push(subtraction); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand(s) for subtraction."); } } else if (ttype == Lexeme.LexemeType.OP_MUL) { try { SyntaxNode right = operandStack.Pop(); SyntaxNode left = operandStack.Pop(); MultiplicationNode multiplication = new MultiplicationNode(left, right); operandStack.Push(multiplication); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand(s) for multiplication."); } } else if (ttype == Lexeme.LexemeType.OP_DIV) { try { SyntaxNode right = operandStack.Pop(); SyntaxNode left = operandStack.Pop(); DivisionNode division = new DivisionNode(left, right); operandStack.Push(division); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand(s) for division."); } } else if (ttype == Lexeme.LexemeType.OP_POW) { try { SyntaxNode exponent = operandStack.Pop(); SyntaxNode baseNode = operandStack.Pop(); PowerNode power = new PowerNode(baseNode, exponent); operandStack.Push(power); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand(s) for exponentiation."); } } else if (ttype == Lexeme.LexemeType.EQ_SIGN) { try { SyntaxNode right = operandStack.Pop(); SyntaxNode left = operandStack.Pop(); EqualsNode eqNode = new EqualsNode(left, right); operandStack.Push(eqNode); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand(s) for assignment."); } } else if (ttype == Lexeme.LexemeType.OP_PLUS_UNARY) { try { SyntaxNode child = operandStack.Pop(); UnaryPlusNode unaryPlus = new UnaryPlusNode(child); operandStack.Push(unaryPlus); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand for unary plus."); } } else if (ttype == Lexeme.LexemeType.OP_MINUS_UNARY) { try { SyntaxNode child = operandStack.Pop(); UnaryMinusNode unaryMinus = new UnaryMinusNode(child); operandStack.Push(unaryMinus); } catch (InvalidOperationException ex) { throw new ParseException("Missing operand for unary minus."); } } else { throw new ParseException("Unexpected token in postfix expression: " + token.simpleRepresentation()); } } else if (input is SyntaxNode) { operandStack.Push(input as SyntaxNode); } else { throw new ParseException("Unexpected object type in postfix expression."); } } if (operandStack.Count == 1) { return(operandStack.Pop()); } else { throw new ParseException("Too many operands in postfix expression."); } }
public void AddFunction(String functionName, int numArguments, FunctionApplyNode.FunctionBody definition) { functionDeclarations.Add(functionName.Trim(), numArguments); functionDefinitions.Add(functionName.Trim(), definition); }