Beispiel #1
0
 def e_Postfix(self, expr1, token, p):
     q = left_binary_ops["Postfix"]
     if q < p:
         return None
     self.consume()
     # postix has lowest prec and is left assoc
     expr2 = self.parse_exp(q + 1)
     return Node(expr2, expr1)
Beispiel #2
0
 def p_SlotSequence(self, token):
     self.consume()
     text = token.text
     if len(text) == 2:
         n = "1"
     else:
         n = text[2:]
     return Node("SlotSequence", Number(n))
Beispiel #3
0
 def parse_binary(self, expr1, token, p):
     tag = token.tag
     q = binary_ops[tag]
     if q < p:
         return None
     self.consume()
     if tag not in right_binary_ops:
         q += 1
     expr2 = self.parse_exp(q)
     # flatten or associate
     if tag in nonassoc_binary_ops and expr1.get_head_name() == tag and not expr1.parenthesised:
         self.tokeniser.sntx_message(token.pos)
         raise InvalidSyntaxError()
     result = Node(tag, expr1, expr2)
     if tag in flat_binary_ops:
         result.flatten()
     return result
Beispiel #4
0
 def testSet(self):
     self.check('x = y', Node('Set', Symbol('x'), Symbol('y')))
     self.check('x := y', Node('SetDelayed', Symbol('x'), Symbol('y')))
     self.check('x ^= y', Node('UpSet', Symbol('x'), Symbol('y')))
     self.check('x ^:= y', Node('UpSetDelayed', Symbol('x'), Symbol('y')))
     self.check('x =.', Node('Unset', Symbol('x')))
     self.check('x/:1=1', Node('TagSet', Symbol('x'), Number('1'), Number('1')))
     self.check('x/:1:=1', Node('TagSetDelayed', Symbol('x'), Number('1'), Number('1')))
     self.check('x/:1=.', Node('TagUnset', Symbol('x'), Number('1')))
     self.check('f /: f[x_] + f[y_] := x + y', 'TagSetDelayed[f, f[x_] + f[y_], x + y]')
Beispiel #5
0
 def parse_binary(self, expr1, token, p):
     tag = token.tag
     q = binary_ops[tag]
     if q < p:
         return None
     self.consume()
     if tag not in right_binary_ops:
         q += 1
     expr2 = self.parse_exp(q)
     # flatten or associate
     if tag in nonassoc_binary_ops and expr1.get_head_name(
     ) == tag and not expr1.parenthesised:
         self.tokeniser.sntx_message(token.pos)
         raise InvalidSyntaxError()
     result = Node(tag, expr1, expr2)
     if tag in flat_binary_ops:
         result.flatten()
     return result
Beispiel #6
0
 def p_Minus(self, token):
     self.consume()
     q = prefix_ops["Minus"]
     expr = self.parse_exp(q)
     if isinstance(expr, Number) and not expr.value.startswith("-"):
         expr.value = "-" + expr.value
         return expr
     else:
         return Node("Times", Number("1", sign=-1), expr).flatten()
Beispiel #7
0
 def e_Infix(self, expr1, token, p):
     q = ternary_ops['Infix']
     if q < p:
         return None
     self.consume()
     expr2 = self.parse_exp(q + 1)
     self.expect('Infix')
     expr3 = self.parse_exp(q + 1)
     return Node(expr2, expr1, expr3)
Beispiel #8
0
 def b_FractionBox(self, box1, token, p):
     q = misc_ops['FractionBox']
     if q < p:
         return None
     if box1 is None:
         box1 = String('')
     self.consume()
     box2 = self.parse_box(q + 1)
     return Node('FractionBox', box1, box2)
Beispiel #9
0
 def p_Minus(self, token):
     self.consume()
     q = prefix_ops['Minus']
     expr = self.parse_exp(q)
     if isinstance(expr, Number) and not expr.value.startswith('-'):
         expr.value = '-' + expr.value
         return expr
     else:
         return Node('Times', Number('-1'), expr).flatten()
Beispiel #10
0
    def testFunctional(self):
        self.check('expr1 @ expr2', Node('expr1', Symbol('expr2')))
        self.check('f @@ expr', Node('Apply', Symbol('f'), Symbol('expr')))
        self.check('f /@ expr', Node('Map', Symbol('f'), Symbol('expr')))

        self.check('f @@@ expr', Node('Apply', Symbol('f'), Symbol('expr'), Node('List', Number('1'))))
        self.check('f //@ expr', Node('MapAll', Symbol('f'), Symbol('expr')))
        self.check('a @@ b @@ c', Node('Apply', Symbol('a'), Node('Apply', Symbol('b'), Symbol('c'))))

        self.check('a /@ b @@ c', 'Map[a, Apply[b, c]]')
        self.check('a @@ b /@ c', 'Apply[a, Map[b, c]]')
Beispiel #11
0
 def parse_e(self):
     result = []
     while self.next().tag != 'END':
         result.append(self.parse_exp(0))
     if len(result) > 1:
         return Node('Times', *result)
     if len(result) == 1:
         return result[0]
     else:
         return None
Beispiel #12
0
 def p_LeftRowBox(self, token):
     self.consume()
     children = []
     self.box_depth += 1
     self.bracket_depth += 1
     token = self.next()
     while token.tag not in ('RightRowBox', 'OtherscriptBox'):
         children.append(self.parse_box(0))
         token = self.next()
     if len(children) == 0:
         result = String('')
     elif len(children) == 1:
         result = children[0]
     else:
         result = Node('RowBox', Node('List', *children))
     self.expect('RightRowBox')
     self.box_depth -= 1
     self.bracket_depth -= 1
     result.parenthesised = True
     return result
Beispiel #13
0
 def testComment(self):
     self.check('145 (* abf *) 345', Node('Times', Number('145'), Number('345')))
     self.check(r'(*"\"\*)', None)
     self.check(r'(**)', None)
     self.check(r'(*)*)', None)
     self.incomplete_error(r'(*(*(*')
     self.incomplete_error(r'(*(*)')
     self.incomplete_error(r'(*(**)')
     self.invalid_error(r'*)')
     self.invalid_error(r'(**)*)')
     self.invalid_error(r'(*(*(**)*)*)*)')
     self.check(r'(*(*)*) (*)*)*)', None)
Beispiel #14
0
 def p_LeftRowBox(self, token):
     self.consume()
     children = []
     self.box_depth += 1
     self.bracket_depth += 1
     token = self.next()
     while token.tag not in ("RightRowBox", "OtherscriptBox"):
         newnode = self.parse_box(0)
         children.append(newnode)
         token = self.next()
     if len(children) == 0:
         result = String("")
     elif len(children) == 1:
         result = children[0]
     else:
         result = Node("RowBox", Node("List", *children))
     self.expect("RightRowBox")
     self.box_depth -= 1
     self.bracket_depth -= 1
     result.parenthesised = True
     return result
Beispiel #15
0
 def e_RawLeftBracket(self, expr, token, p):
     q = all_ops['Part']
     if q < p:
         return None
     self.consume()
     self.bracket_depth += 1
     token = self.next_noend()
     if token.tag == 'RawLeftBracket':
         self.consume()
         seq = self.parse_seq()
         self.expect('RawRightBracket')
         self.expect('RawRightBracket')
         self.bracket_depth -= 1
         return Node('Part', expr, *seq)
     else:
         seq = self.parse_seq()
         self.expect('RawRightBracket')
         self.bracket_depth -= 1
         result = Node(expr, *seq)
         result.parenthesised = True
         return result
Beispiel #16
0
 def p_Slot(self, token):
     self.consume()
     text = token.text
     if len(text) == 1:
         n = Number('1')
     else:
         n = text[1:]
         if n.isdigit():
             n = Number(n)
         else:
             n = String(n)
     return Node('Slot', n)
Beispiel #17
0
 def e_RawLeftBracket(self, expr, token, p):
     q = all_ops['Part']
     if q < p:
         return None
     self.consume()
     self.bracket_depth += 1
     token = self.next_noend()
     if token.tag == 'RawLeftBracket':
         self.consume()
         seq = self.parse_seq()
         self.expect('RawRightBracket')
         self.expect('RawRightBracket')
         self.bracket_depth -= 1
         return Node('Part', expr, *seq)
     else:
         seq = self.parse_seq()
         self.expect('RawRightBracket')
         self.bracket_depth -= 1
         result = Node(expr, *seq)
         result.parenthesised = True
         return result
Beispiel #18
0
 def testSet(self):
     self.check("x = y", Node("Set", Symbol("x"), Symbol("y")))
     self.check("x := y", Node("SetDelayed", Symbol("x"), Symbol("y")))
     self.check("x ^= y", Node("UpSet", Symbol("x"), Symbol("y")))
     self.check("x ^:= y", Node("UpSetDelayed", Symbol("x"), Symbol("y")))
     self.check("x =.", Node("Unset", Symbol("x")))
     self.check("x/:1=1",
                Node("TagSet", Symbol("x"), Number("1"), Number("1")))
     self.check(
         "x/:1:=1",
         Node("TagSetDelayed", Symbol("x"), Number("1"), Number("1")))
     self.check("x/:1=.", Node("TagUnset", Symbol("x"), Number("1")))
     self.check("f /: f[x_] + f[y_] := x + y",
                "TagSetDelayed[f, f[x_] + f[y_], x + y]")
Beispiel #19
0
    def testList(self):
        self.check('{x, y}', Node('List', Symbol('x'), Symbol('y')))

        self.check('{1}', Node('List', Number('1')))
        self.check('{}', Node('List'))
        self.check('{a,}', Node('List', Symbol('a'), Symbol('Null')))
        self.check('{,}', Node('List', Symbol('Null'), Symbol('Null')))

        self.check('{a, b,}',
                   Node('List', Symbol('a'), Symbol('b'), Symbol('Null')))

        self.check('{,a}', Node('List', Symbol('Null'), Symbol('a')))
        self.check('{, a, b}',
                   Node('List', Symbol('Null'), Symbol('a'), Symbol('b')))
        self.check(
            '{,a,b,}',
            Node('List', Symbol('Null'), Symbol('a'), Symbol('b'),
                 Symbol('Null')))
Beispiel #20
0
 def testComment(self):
     self.check("145 (* abf *) 345",
                Node("Times", Number("145"), Number("345")))
     self.check(r'(*"\"\*)', None)
     self.check(r"(**)", None)
     self.check(r"(*)*)", None)
     self.incomplete_error(r"(*(*(*")
     self.incomplete_error(r"(*(*)")
     self.incomplete_error(r"(*(**)")
     self.invalid_error(r"*)")
     self.invalid_error(r"(**)*)")
     self.invalid_error(r"(*(*(**)*)*)*)")
     self.check(r"(*(*)*) (*)*)*)", None)
Beispiel #21
0
    def testList(self):
        self.check("{x, y}", Node("List", Symbol("x"), Symbol("y")))

        self.check("{1}", Node("List", Number("1")))
        self.check("{}", Node("List"))
        self.check("{a,}", Node("List", Symbol("a"), Symbol("Null")))
        self.check("{,}", Node("List", Symbol("Null"), Symbol("Null")))

        self.check("{a, b,}",
                   Node("List", Symbol("a"), Symbol("b"), Symbol("Null")))

        self.check("{,a}", Node("List", Symbol("Null"), Symbol("a")))
        self.check("{, a, b}",
                   Node("List", Symbol("Null"), Symbol("a"), Symbol("b")))
        self.check(
            "{,a,b,}",
            Node("List", Symbol("Null"), Symbol("a"), Symbol("b"),
                 Symbol("Null")),
        )
Beispiel #22
0
 def e_TagSet(self, expr1, token, p):
     q = all_ops['Set']
     if q < p:
         return None
     self.consume()
     expr2 = self.parse_exp(q + 1)
     # examine next token
     token = self.next_noend()
     tag = token.tag
     if tag == 'Set':
         head = 'TagSet'
     elif tag == 'SetDelayed':
         head = 'TagSetDelayed'
     elif tag == 'Unset':
         head = 'TagUnset'
     else:
         self.tokeniser.sntx_message(token.pos)
         raise InvalidSyntaxError()
     self.consume()
     if head == 'TagUnset':
         return Node(head, expr1, expr2)
     expr3 = self.parse_exp(q + 1)
     return Node(head, expr1, expr2, expr3)
Beispiel #23
0
 def parse_p(self):
     token = self.next_noend()
     tag = token.tag
     method = getattr(self, 'p_' + tag, None)
     if method is not None:
         return method(token)
     elif tag in prefix_ops:
         self.consume()
         q = prefix_ops[tag]
         child = self.parse_exp(q)
         return Node(tag, child)
     else:
         self.tokeniser.sntx_message(token.pos)
         raise InvalidSyntaxError()
Beispiel #24
0
 def e_RawColon(self, expr1, token, p):
     head_name = expr1.get_head_name()
     if head_name == 'Symbol':
         head = 'Pattern'
     elif head_name in ('Blank', 'BlankSequence', 'BlankNullSequence',
                        'Pattern', 'Optional'):
         head = 'Optional'
     else:
         return None
     q = all_ops[head]
     if p == 151:
         return None
     self.consume()
     expr2 = self.parse_exp(q + 1)
     return Node(head, expr1, expr2)
Beispiel #25
0
    def testExpression(self):
        self.check('expr1[expr2]', Node('expr1', Symbol('expr2')))
        self.check('expr1[expr2][expr3]',
                   Node(Node('expr1', Symbol('expr2')), Symbol('expr3')))
        self.check('expr1[[expr2]]',
                   Node('Part', Symbol('expr1'), Symbol('expr2')))
        self.check(
            'expr1[[expr2, expr3]]',
            Node('Part', Symbol('expr1'), Symbol('expr2'), Symbol('expr3')))
        self.check(
            'expr1[[expr2]][[expr3]]',
            Node('Part', Node('Part', Symbol('expr1'), Symbol('expr2')),
                 Symbol('expr3')))

        self.check('expr1 ~ expr2 ~ expr3',
                   Node('expr2', Symbol('expr1'), Symbol('expr3')))
        self.check('x~f~y', 'f[x, y]')
Beispiel #26
0
    def testTimes(self):
        self.check('1 2', Node('Times', Number('1'), Number('2')))
        self.check('1*2', Node('Times', Number('1'), Number('2')))

        self.check('1 2 3', Node('Times', Number('1'), Number('2'),
                                 Number('3')))
        self.check(
            '(1 2) 3',
            Node('Times', Node('Times', Number('1'), Number('2')),
                 Number('3')))
        self.check('1*2*3', Node('Times', Number('1'), Number('2'),
                                 Number('3')))

        self.check(
            'x ^ 2 y',
            Node('Times', Node('Power', Symbol('x'), Number('2')),
                 Symbol('y')))
Beispiel #27
0
    def e_Semicolon(self, expr1, token, p):
        q = flat_binary_ops['CompoundExpression']
        if q < p:
            return None
        self.consume()

        # XXX this has to come before call to self.next()
        pos = self.tokeniser.pos
        messages = list(self.feeder.messages)

        # So that e.g. 'x = 1;' doesn't wait for newline in the frontend
        tag = self.next().tag
        if tag == 'END' and self.bracket_depth == 0:
            expr2 = Symbol('Null')
            return Node('CompoundExpression', expr1, expr2).flatten()

        # XXX look for next expr otherwise backtrack
        try:
            expr2 = self.parse_exp(q + 1)
        except TranslateError:
            self.backtrack(pos)
            self.feeder.messages = messages
            expr2 = Symbol('Null')
        return Node('CompoundExpression', expr1, expr2).flatten()
Beispiel #28
0
 def e_MessageName(self, expr1, token, p):
     leaves = [expr1]
     while self.next().tag == 'MessageName':
         self.consume()
         token = self.next()
         if token.tag == 'Symbol':
             # silently convert Symbol to String
             self.consume()
             leaf = String(token.text)
         elif token.tag == 'String':
             leaf = self.p_String(token)
         else:
             self.tokeniser.sntx_message(token.pos)
             raise InvalidSyntaxError()
         leaves.append(leaf)
     return Node('MessageName', *leaves)
Beispiel #29
0
 def testOptional(self):
     self.check('x:expr', Node('Pattern', Symbol('x'), Symbol('expr')))
     self.check(
         'x_:expr',
         Node('Optional', Node('Pattern', Symbol('x'), Node('Blank')),
              Symbol('expr')))
     self.check(
         'f:a|b',
         Node('Pattern', Symbol('f'),
              Node('Alternatives', Symbol('a'), Symbol('b'))))
     self.check('rev:(True|False):False',
                'Optional[Pattern[rev, Alternatives[True, False]], False]')
Beispiel #30
0
    def testTimes(self):
        self.check("1 2", Node("Times", Number("1"), Number("2")))
        self.check("1*2", Node("Times", Number("1"), Number("2")))

        self.check("1 2 3", Node("Times", Number("1"), Number("2"),
                                 Number("3")))
        self.check(
            "(1 2) 3",
            Node("Times", Node("Times", Number("1"), Number("2")),
                 Number("3")),
        )
        self.check("1*2*3", Node("Times", Number("1"), Number("2"),
                                 Number("3")))

        self.check(
            "x ^ 2 y",
            Node("Times", Node("Power", Symbol("x"), Number("2")),
                 Symbol("y")),
        )
Beispiel #31
0
    def testExpression(self):
        self.check("expr1[expr2]", Node("expr1", Symbol("expr2")))
        self.check("expr1[expr2][expr3]",
                   Node(Node("expr1", Symbol("expr2")), Symbol("expr3")))
        self.check("expr1[[expr2]]",
                   Node("Part", Symbol("expr1"), Symbol("expr2")))
        self.check(
            "expr1[[expr2, expr3]]",
            Node("Part", Symbol("expr1"), Symbol("expr2"), Symbol("expr3")),
        )
        self.check(
            "expr1[[expr2]][[expr3]]",
            Node("Part", Node("Part", Symbol("expr1"), Symbol("expr2")),
                 Symbol("expr3")),
        )

        self.check("expr1 ~ expr2 ~ expr3",
                   Node("expr2", Symbol("expr1"), Symbol("expr3")))
        self.check("x~f~y", "f[x, y]")
Beispiel #32
0
    def testFunctional(self):
        self.check("expr1 @ expr2", Node("expr1", Symbol("expr2")))
        self.check("f @@ expr", Node("Apply", Symbol("f"), Symbol("expr")))
        self.check("f /@ expr", Node("Map", Symbol("f"), Symbol("expr")))

        self.check(
            "f @@@ expr",
            Node("Apply", Symbol("f"), Symbol("expr"),
                 Node("List", Number("1"))),
        )
        self.check("f //@ expr", Node("MapAll", Symbol("f"), Symbol("expr")))
        self.check(
            "a @@ b @@ c",
            Node("Apply", Symbol("a"), Node("Apply", Symbol("b"),
                                            Symbol("c"))),
        )

        self.check("a /@ b @@ c", "Map[a, Apply[b, c]]")
        self.check("a @@ b /@ c", "Apply[a, Map[b, c]]")