示例#1
0
def unary_prefix_evaluator(parser, sym):
    arg = parser.parse_to(sym.rprio)
    if arg is None:
        return CompositeNode(sym.token,
                             [Node(lexer.Token('ERROR', 'MISSING VALUE'))])
    else:
        return CompositeNode(sym.token, [arg])
def question_evaluator(args):
    if (len(args) != 5 or type(args[0]) == SymbolDesc
            or type(args[1]) != SymbolDesc or args[1].symbol != '?'
            or type(args[2]) == SymbolDesc or type(args[3]) != SymbolDesc
            or args[3].symbol != ':' or type(args[4]) == SymbolDesc):
        return CompositeNode('? ERROR', args)
    return CompositeNode('?', [args[0], args[2], args[4]])
示例#3
0
def binary_evaluator(parser, left_arg, sym):
    right_arg = parser.parse_to(sym.rprio)
    if right_arg is None:
        return CompositeNode(
            sym.token,
            [left_arg, Node(lexer.Token('ERROR', 'MISSING VALUE'))])
    else:
        return CompositeNode(sym.token, [left_arg, right_arg])
def open_bracket_evaluator(args):
    if (len(args) == 4 and type(args[0]) != SymbolDesc
            and type(args[1]) == SymbolDesc and args[1].symbol == '['
            and type(args[2]) != SymbolDesc and type(args[3]) == SymbolDesc
            and args[3].symbol == ']'):
        return CompositeNode('get', [args[0], args[2]])
    else:
        return CompositeNode('[ ERROR', args)
def unary_evaluator(args):
    if len(args) != 2:
        return CompositeNode('UNARY ERROR', args)
    if type(args[0]) == SymbolDesc and type(args[1]) != SymbolDesc:
        return CompositeNode(args[0].symbol, [args[1]])
    elif type(args[0]) != SymbolDesc and type(args[1]) == SymbolDesc:
        return CompositeNode('post' + args[1].symbol, [args[0]])
    else:
        return CompositeNode('UNARY ERROR', args)
示例#6
0
def question_evaluator(parser, left_arg, sym):
    true_exp = parser.parse_to(sym.rprio)
    sym = parser.postfix_sym()
    if sym is not None and sym.token == ':':
        parser.advance()
        false_exp = parser.parse_to(sym.rprio)
        return CompositeNode('?', [left_arg, true_exp, false_exp])
    else:
        return CompositeNode('? ERROR', [left_arg, true_exp])
示例#7
0
def postfix_open_bracket_evaluator(parser, left_arg, sym):
    result = parser.parse_to(sym.rprio)
    if parser.cur_token is not None:
        if parser.cur_token.lexem == ']':
            parser.advance()
            return CompositeNode('get ' + str(left_arg), [result])
        elif parser.cur_token.lexem == ')':
            parser.advance()
            return CompositeNode('get [) ' + str(left_arg), [result])
    return CompositeNode('[ ERROR', [left_arg, result])
示例#8
0
def prefix_open_parenthesis_evaluator(parser, sym):
    result = parser.parse_to(sym.rprio)
    if parser.cur_token is not None:
        if parser.cur_token.lexem == ')':
            parser.advance()
            return result
        elif parser.cur_token.lexem == ']':
            parser.advance()
            return CompositeNode('(] ERROR', [result])
    else:
        return CompositeNode('( ERROR', [result])
示例#9
0
def unary_or_binary_evaluator(args):
    if (len(args) == 2 and type(args[0]) == SymbolDesc
            and type(args[1]) != SymbolDesc):
        return CompositeNode(args[0].symbol, [args[1]])
    elif (len(args) == 2 and type(args[0]) != SymbolDesc
          and type(args[1]) == SymbolDesc):
        return CompositeNode('post' + args[1].symbol, [args[0]])
    elif (len(args) == 3 and type(args[0]) != SymbolDesc
          and type(args[1]) == SymbolDesc and type(args[2]) != SymbolDesc):
        return CompositeNode(args[1].symbol, [args[0], args[2]])
    else:
        return CompositeNode('1,2-ARY ERROR', args)
 def parse(self, s):
     self.reset()
     previous_was_id = False
     for tk in lexer.tokenize(s):
         if tk.kind == 'NUMBER' or tk.kind == 'ID':
             self.values_stack.append(Node(tk))
         elif tk.lexem == '(':
             self.operators_stack.append(self.operators[tk.lexem])
             self.previous_coma_interpretation.append(
                 self.coma_interpretation)
             if previous_was_id:
                 self.coma_interpretation = 2
             else:
                 self.coma_interpretation = 0
         elif tk.lexem == '[':
             self.operators_stack.append(self.operators[tk.lexem])
             self.previous_coma_interpretation.append(
                 self.coma_interpretation)
             self.coma_interpretation = 1
         elif tk.lexem in self.operators:
             self.push_operator(self.operators[tk.lexem])
             if tk.lexem == ')':
                 self.operators_stack.pop()
                 self.operators_stack.pop()
                 if self.coma_interpretation == 2:
                     val2 = self.values_stack.pop()
                     val1 = self.values_stack.pop()
                     self.values_stack.append(
                         CompositeNode('call', [val1, val2]))
                 self.coma_interpretation = self.previous_coma_interpretation.pop(
                 )
             elif tk.lexem == ']':
                 self.operators_stack.pop()
                 self.operators_stack.pop()
                 val2 = self.values_stack.pop()
                 val1 = self.values_stack.pop()
                 self.values_stack.append(
                     CompositeNode('index', [val1, val2]))
                 self.coma_interpretation = self.previous_coma_interpretation.pop(
                 )
         else:
             raise RuntimeError('Syntax error at {}'.format(tk.lexem))
         previous_was_id = tk.kind == 'ID'
     while len(self.operators_stack) > 0:
         self.evaluate_operator()
     if len(self.values_stack) != 1:
         raise RuntimeError('Internal error: value left on stack')
     return self.values_stack.pop()
示例#11
0
def NullIncDec(p, token, rbp):
    """ ++x or ++x[1] """
    right = p.ParseUntil(rbp)
    if right.token not in ('ID', 'get') and (
            right.token is Token and right.token.kind not in ('ID', 'get')):
        raise ParseError("Can't assign to %r (%s)" % (right, right.token))
    return CompositeNode(token.kind, [right])
示例#12
0
def LeftIndex(p, token, unused_rbp, left):
    """ index f[x+1] or f[x][y] """
    if left.token.kind not in ('ID', 'get'):
        raise ParseError("%s can't be indexed" % left)
    index = p.ParseUntil(0)
    p.Eat("]")
    token.kind = 'get'
    return CompositeNode(token.kind, [left, index])
def prefix_close_parenthesis(parser):
    op1 = parser.operators_stack.pop()
    if op1.oper != '(' or op1.evaluator != infix_open_parenthesis:
        parser.dump()
        raise RuntimeError('Empty parenthesis')
    val1 = parser.values_stack.pop()
    parser.values_stack.append(CompositeNode('call', [val1]))
    parser.waiting_value = False
示例#14
0
def LeftComma(p, token, rbp, left):
    """ foo, bar, baz - Could be sequencing operator, or tuple without parens """
    r = p.ParseUntil(rbp)
    if not left.parenthesis and left.token == ',':  # Keep adding more children
        left.children.append(r)
        return left
    children = [left, r]
    return CompositeNode(token.kind, children)
示例#15
0
def NullPrefixOp(p, token, rbp):
    """Prefix operator
    Low precedence:  return, raise, etc.
      return x+y is return (x+y), not (return x) + y
    High precedence: logical negation, bitwise complement, etc.
      !x && y is (!x) && y, not !(x && y)
    """
    r = p.ParseUntil(rbp)
    return CompositeNode(token.kind, [r])
def postfix_close_brackets(parser):
    op1 = parser.operators_stack.pop()
    op2 = parser.operators_stack.pop()
    if op2.oper != '[' or op2.evaluator != infix_open_brackets:
        parser.dump()
        raise RuntimeError('Unopened close bracket')
    val1 = parser.values_stack.pop()
    val2 = parser.values_stack.pop()
    parser.values_stack.append(CompositeNode('get', [val2, val1]))
示例#17
0
def coma_evaluator(parser, left_arg, sym):
    args = [left_arg]
    while True:
        args.append(parser.parse_to(sym.rprio))
        sym = parser.postfix_sym()
        if sym is None or sym.token != ',':
            break
        parser.advance()
    return CompositeNode(',', args)
def infix_colon(parser):
    op1 = parser.operators_stack.pop()
    op2 = parser.operators_stack.pop()
    if op2.oper != '?':
        parser.dump()
        raise RuntimeError(': wihout ?')
    val1 = parser.values_stack.pop()
    val2 = parser.values_stack.pop()
    val3 = parser.values_stack.pop()
    parser.values_stack.append(CompositeNode('?', [val3, val2, val1]))
def coma_evaluator(parser):
    oper = parser.operators_stack.pop()
    val2 = parser.values_stack.pop()
    val1 = parser.values_stack.pop()
    if type(val1
            ) is CompositeNode and val1.token == ',' and not val1.parenthesis:
        val1.children.append(val2)
        parser.values_stack.append(val1)
    else:
        parser.values_stack.append(CompositeNode(oper.oper, [val1, val2]))
 def parse_for_operator(self, tk):
     if tk.lexem in self.postfix_actions:
         self.postfix_actions[tk.lexem](self)
     elif tk.lexem in self.postfix_operators:
         self.push_operator(self.postfix_operators[tk.lexem])
     elif tk.lexem in self.infix_operators:
         self.waiting_value = True
         self.push_operator(self.infix_operators[tk.lexem])
     else:
         val = self.values_stack.pop()
         self.values_stack.append(
             CompositeNode('MISSING OPERATOR', [val, Node(tk)]))
def open_parenthesis_evaluator(args):
    if (len(args) == 3 and type(args[0]) == SymbolDesc
            and args[0].symbol == '(' and type(args[1]) != SymbolDesc
            and type(args[2]) == SymbolDesc and args[2].symbol == ')'):
        return args[1]
    elif (len(args) == 3 and type(args[0]) != SymbolDesc
          and type(args[1]) == SymbolDesc and args[1].symbol == '('
          and type(args[2]) == SymbolDesc and args[2].symbol == ')'):
        return CompositeNode('call', [args[0]])
    elif (len(args) == 4 and type(args[0]) != SymbolDesc
          and type(args[1]) == SymbolDesc and args[1].symbol == '('
          and type(args[2]) != SymbolDesc and type(args[3]) == SymbolDesc
          and args[3].symbol == ')'):
        if args[2].token == ',':
            callargs = args[2].children
        else:
            callargs = [args[2]]
        callargs.insert(0, args[0])
        return CompositeNode('call', callargs)
    else:
        return CompositeNode('( ERROR', args)
示例#22
0
def LeftFuncCall(p, token, unused_rbp, left):
    """ Function call f(a, b). """
    children = [left]
    # f(x) or f[i](x)
    # if left.token.kind not in ('ID', 'get'):
    #  raise tdop.ParseError("%s can't be called" % left)
    while not p.AtToken(')'):
        # We don't want to grab the comma, e.g. it is NOT a sequence operator.
        children.append(p.ParseUntil(COMMA_PREC))
        if p.AtToken(','):
            p.Next()
    p.Eat(")")
    token.kind = 'call'
    return CompositeNode(token.kind, children)
示例#23
0
def LeftTernaryOp(p, token, rbp, left):
    """ e.g. a > 1 ? x : y """
    # 0 binding power since any operators allowed until ':'.  See:
    #
    # http://en.cppreference.com/w/c/language/operator_precedence#cite_note-2
    #
    # "The expression in the middle of the conditional operator (between ?  and
    # :) is parsed as if parenthesized: its precedence relative to ?: is
    # ignored."
    true_expr = p.ParseUntil(0)
    p.Eat(':')
    false_expr = p.ParseUntil(rbp)
    children = [left, true_expr, false_expr]
    return CompositeNode(token.kind, children)
def postfix_close_parenthesis(parser):
    op1 = parser.operators_stack.pop()
    op2 = parser.operators_stack.pop()
    if op2.oper != '(':
        parser.dump()
        raise RuntimeError('Unopened close parenthesis')
    if op2.evaluator == infix_open_parenthesis:
        val1 = parser.values_stack.pop()
        val2 = parser.values_stack.pop()
        if type(val1) == CompositeNode and val1.token == ',':
            args = [val2] + val1.children
        else:
            args = [val2, val1]
        parser.values_stack.append(CompositeNode('call', args))
    else:
        parser.values_stack[-1].parenthesis = True
示例#25
0
 def parse(self, s):
     self.reset(s)
     while True:
         sym = self.cur_sym(type(self.stack[-1]) == SymbolDesc)
         if sym is None:
             break
         while self.tos_symbol().rprio > sym.lprio:
             self.evaluate()
             sym = self.cur_sym(False)
         self.stack.append(sym)
         self.advance()
     while len(self.stack) > 2 or (len(self.stack) == 2
                                   and type(self.stack[-1]) == SymbolDesc):
         self.evaluate()
     if len(self.stack) == 1:
         res = None
     elif len(self.stack) == 2:
         res = self.stack[1]
     if self.cur_token is not None:
         res = CompositeNode('REMAINING INPUT', [res, self.cur_token])
     return res
示例#26
0
def postfix_open_parenthesis_evaluator(parser, left_arg, sym):
    if parser.cur_token is not None and parser.cur_token.lexem == ')':
        parser.advance()
        return CompositeNode('call ' + str(left_arg), [])
    else:
        result = parser.parse_to(sym.rprio)
        if parser.cur_token is not None:
            if parser.cur_token.lexem == ')':
                parser.advance()
                if result.token == ',':
                    return CompositeNode('call ' + str(left_arg),
                                         result.children)
                else:
                    return CompositeNode('call ' + str(left_arg), [result])
            elif parser.cur_token.lexem == ']':
                parser.advance()
                if result.token == ',':
                    return CompositeNode('call (] ' + str(left_arg),
                                         result.children)
                else:
                    return CompositeNode('call (] ' + str(left_arg), [result])

        return CompositeNode('( ERROR', [result])
def binary_evaluator(parser):
    val2 = parser.stack.pop()
    oper = parser.stack.pop()
    val1 = parser.stack.pop()
    parser.stack.append(CompositeNode(oper.oper, [val1, val2]))
def unary_evaluator(parser):
    val = parser.stack.pop()
    oper = parser.stack.pop()
    parser.stack.append(CompositeNode(oper.oper, [val]))
示例#29
0
def unary_evaluator(parser):
    oper = parser.operators_stack.pop()
    parser.values_stack.append(CompositeNode(oper.oper, [parser.values_stack.pop()]))
def binary_evaluator(args):
    if len(args) != 3 or type(
            args[0]) == SymbolDesc or type(args[1]) != SymbolDesc or type(
                args[2]) == SymbolDesc:
        return CompositeNode('BINARY ERROR', args)
    return CompositeNode(args[1].symbol, [args[0], args[2]])