import logging
import ply.yacc as yacc
import hxl.model
import hxl.formulas.functions as f

logger = logging.getLogger(__name__)

from hxl.formulas.lexer import tokens

precedence = [
    ['left', 'PLUS', 'MINUS'],
    ['left', 'TIMES', 'DIVIDE', 'MODULO'],
    ['right', 'UMINUS'],
]

def p_expression_const(p):
    """expression : INT
                  | FLOAT
                  | STRING
    """
    p[0] = [f.const, [p[1]]]

def p_expression_group(p):
    'expression : LPAREN expression RPAREN'
    p[0] = p[2]

def p_expression_plus(p):
    'expression : expression PLUS expression'
    p[0] = [f.add, [p[1], p[3]]]

def p_expression_minus(p):
    'expression : expression MINUS expression'
    p[0] = [f.subtract, [p[1], p[3]]]

def p_expression_times(p):
    'expression : expression TIMES expression'
    p[0] = [f.multiply, [p[1], p[3]]]

def p_expression_divide(p):
    'expression : expression DIVIDE expression'
    p[0] = [f.divide, [p[1], p[3]]]

def p_expression_modulo(p):
    'expression : expression MODULO expression'
    p[0] = [f.modulo, [p[1], p[3]]]

def p_expression_uminus(p):
    'expression : MINUS expression %prec UMINUS'
    p[0] = [f.subtract, [0, p[2]]]

def p_expression_tagpattern(p):
    'expression : TAGPATTERN'
    p[0] = [f.tagref, [hxl.model.TagPattern.parse(p[1])]]

def p_expression_function(p):
    'expression : NAME LPAREN args RPAREN'
    p[0] = [f.function, [p[1]] + p[3]]

def p_args_multiple(p):
    'args : expression COMMA args'
    p[0] = [p[1]] + p[3]

def p_args_single(p):
    'args : expression'
    p[0] = [p[1]]

def p_args_empty(p):
    'args :'
    p[0] = []

# Error rule for syntax errors
def p_error(p):
    logger.error("Syntax error: %s", str(p))

parser = yacc.yacc()
