147 lines
5.9 KiB
Objective-C
147 lines
5.9 KiB
Objective-C
//
|
|
// MPExpressionParser.h
|
|
// MathPad
|
|
//
|
|
// Created by Kim Wittenburg on 16.11.14.
|
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
|
//
|
|
|
|
|
|
/*!
|
|
@header
|
|
The <code>MPExpressionParser</code> converts a <code>@link
|
|
MPExpression@/link</code> instance into a <code>@link
|
|
//apple_ref/occ/cl/MPParsedExpression@/link</code> instance. The rules that are
|
|
used for parsing expressions are consistent with general math rules. For example
|
|
operator precedence and parenthesis are regarded. However there may still be
|
|
ambiguous input. The parser solves them by using the following rules:
|
|
|
|
1. Powers and factorials apply to the value that <b>directly</b> precedes them.
|
|
It is invalid if a power or factorial symbol is preceded by a space.
|
|
2. Powers and factorials chained behind each other apply to the value before the
|
|
first power or factorial symbol in the chain (provided that rule 1 is
|
|
satisfied). All powers and factorials apply to that value in the order of
|
|
occurence. For example <code>2³!</code> is valid and equal to
|
|
<code>(2³)!</code>.
|
|
3. Elementary functions like <code>sin</code>, <code>cos</code> or
|
|
<code>ln</code> can be chained. <code>sincos(2)</code> is equal to
|
|
<code>sin(cos(2))</code>.
|
|
4. Subsequent elementary functions with values are implicitly multiplied.
|
|
<code>sin3cos2</code> is equal to <code>sin(3)⋅cos(2)</code>.
|
|
5. The value of an elementary function is either exactly one generic function
|
|
(instances of a <code>@link MPFunction@/link</code> subclass) or a group of
|
|
numbers and variables that does not contain a multiplication, plus or minus
|
|
sign. <code>sin2a⋅3</code> is equal to <code>(sin(2a))⋅3</code>.
|
|
|
|
Besides the rules above the parser accepts inputs containing the following
|
|
constructs:
|
|
|
|
1. Chained plus and minus signs (e.g. <code>++-+--3</code> is equal to
|
|
<code>-3</code>).
|
|
2. Implicit multiplication. <code>2a3</code> is equal to <code>2⋅a⋅3</code>.
|
|
*/
|
|
|
|
|
|
|
|
@class MPExpressionParser, MPExpression, MPParsedExpression;
|
|
|
|
|
|
/*!
|
|
@class MPExpressionParser
|
|
@abstract An instance of this class can parse an expression.
|
|
|
|
@discussion Parsing an expression means converting it into a <code>@link
|
|
//apple_ref/occ/cl/MPParsedExpression@/link</code> instance. One
|
|
parser can only process one expression. After the parser has been
|
|
constructed it should start processing the expression before it
|
|
is mutated. For the same reason parsers should not be recycled
|
|
but instead recreated when needed.
|
|
*/
|
|
@interface MPExpressionParser : NSObject
|
|
|
|
/*!
|
|
@property expression
|
|
@abstract The receiver's expression.
|
|
*/
|
|
@property (readonly, nonatomic, strong) MPExpression *expression;
|
|
|
|
|
|
/*!
|
|
@method initWithExpression:
|
|
@abstract Initializes a new <code>MPExpressionParser</code>.
|
|
|
|
@discussion After this method returns the parser is ready to parse the given
|
|
<code>expression</code>. If the expression is mutated between the
|
|
creation of the parser and the actual parsing process unexpected
|
|
behaviour may occur.
|
|
|
|
This is the designated initializer for the
|
|
<code>MPExpressionParser</code> class.
|
|
|
|
@param expression
|
|
The expression that is supposed to be parsed.
|
|
|
|
@return A newly initialized expression parser.
|
|
*/
|
|
- (instancetype)initWithExpression:(MPExpression *)expression; /* designated initializer */
|
|
|
|
|
|
/*!
|
|
@method parse:
|
|
@abstract Parses the receiver's expression.
|
|
|
|
@discussion If the expression contains any syntax errors they will be
|
|
returned indirectly through the <code>errors</code> parameter. In
|
|
that case <code>nil</code> is returned. If no errors occur it is
|
|
not modified.
|
|
|
|
This is a convenience method that calls <code>@link
|
|
parseExpectingVariableDefinition:errors:@/link</code> with
|
|
<code>NO</code> as the first argument.
|
|
|
|
@param errors
|
|
If the parsed expression contains syntax errors this parameter
|
|
will be set to an array containing at least one
|
|
<code>NSError</code> instance. This parameter is never set to an
|
|
empty array.
|
|
|
|
If you are not interested in errors, pass <code>NULL</code>.
|
|
|
|
@return The parsed expression or <code>nil</code> if the parsed
|
|
expression contains syntax errors.
|
|
*/
|
|
- (MPParsedExpression *)parse:(NSArray *__autoreleasing *)errors;
|
|
|
|
|
|
/*!
|
|
@method parseExpectingVariableDefinition:errors:
|
|
@abstract Parses the receiver's expression.
|
|
|
|
@discussion If the expression contains any syntax errors they will be
|
|
returned indirectly through the <code>errors</code> parameter. In
|
|
that case <code>nil</code> is returned. If no errors occur it is
|
|
not modified.
|
|
|
|
@param flag
|
|
If set to <code>YES</code> the parser expects the expression to
|
|
begin with a variable definition, that is a single letter
|
|
followed by an equals sign (exept for spaces). If set to
|
|
<code>NO</code> there must not be a variable definition.
|
|
|
|
@param errors
|
|
If the parsed expression contains syntax errors this parameter
|
|
will be set to an array containing at least one
|
|
<code>NSError</code> instance. This parameter is never set to an
|
|
empty array.
|
|
|
|
If you are not interested in errors, pass <code>NULL</code>.
|
|
|
|
@return The parsed expression or <code>nil</code> if the parsed
|
|
expression contains syntax errors.
|
|
*/
|
|
|
|
- (MPParsedExpression *)parseExpectingVariableDefinition:(BOOL)flag
|
|
errors:(NSArray *__autoreleasing *)errors;
|
|
|
|
@end
|