%{
    #import "MPMath.h"
    #define AT @
    
    MPParsedElement *parseResult;
    
    int yylex();
    int yyparse();
    FILE *yyin;
    
    void yyerror(const char *s);
%}

%error-verbose

%initial-action
{
    parseResult = [[MPParsedElement alloc] init];
};

%union {
	double number;
}
    /* Terminals */
%token PLUS
%left MINUS
%token DOT
%token <number> NUMBER

    /* Nonterminals */
%type <number> summands
%type <number> factor
%type <number> product

%%

element:
        factor                   { parseResult.isFactor = YES;
                                   parseResult.factor = $1;
                                 }
        | operator
        | prefix summands suffix
        ;

factor:
        DOT product DOT { $$ = $2;
                        }
        | DOT product   { $$ = $2;
                        }
        | product DOT   { $$ = $1;
                        }
        | product       { $$ = $1;
                        }
        ;

product:
        product DOT product { $$ = $1 * $3;
                            }
        | product product   { $$ = $1 * $2;
                            }
        | NUMBER            { $$ = $1;
                            }
        ;

operator:
        PLUS    { parseResult.suffixMultiplicator = 1;
                  parseResult.hasSuffixMultiplicator = YES;
                }
        | MINUS { parseResult.suffixMultiplicator = -1;
                  parseResult.hasSuffixMultiplicator = YES;
                  NSLog(AT"Op");
                }
        | DOT   { parseResult.isFactor = YES;
                  parseResult.factor = 1;
                }
        |       { parseResult.isFactor = YES;
                  parseResult.factor = 1;
                }
        ;

prefix:
        DOT product { parseResult.prefixMultiplicator = $2;
                      parseResult.hasPrefixMultiplicator = YES;
                      parseResult.prefixOperatorExplicit = YES;
                    }
        | product   { parseResult.prefixMultiplicator = $1;
                      parseResult.hasPrefixMultiplicator = YES;
                      parseResult.prefixOperatorExplicit = YES;
                    }
        |           { parseResult.hasPrefixMultiplicator = NO;
                    }
        ;

summands:
        summands summand
        | summand
        ;

summand:
        PLUS product    { [parseResult.summands addObject:AT($2)];
                        }
        | MINUS product { [parseResult.summands addObject:AT(-$2)];
                        }
        ;

suffix:
        PLUS    { parseResult.suffixMultiplicator = 1;
                  parseResult.hasSuffixMultiplicator = YES;
                }
        | MINUS { parseResult.suffixMultiplicator = -1;
                  parseResult.hasSuffixMultiplicator = YES;
                }
        | DOT   { parseResult.suffixMultiplicator = 0;
                  parseResult.hasSuffixMultiplicator = YES;
                }
        |       { parseResult.hasSuffixMultiplicator = NO;
                }
        ;

%%

void yyerror(const char *s) {
    NSLog(@"EEK, parse error!  Message: %s", s);
	// might as well halt now:
	exit(-1);
}