Example #1
0
    def parse_expression(self, scope):
        """Parse an expression.

        Expressions may contain other forms as well, a expression is the
        'other' type of sentence. They must match a known of sentence in
        the scope.

        :param scope: The scope the expression is being parsed within.
        :return: A Sentence."""
        token = next(self._token_stream)
        if isinstance(token, ValueToken):
            return Sentence([token])
        elif not isinstance(token, FirstToken):
            raise ParseError('Cannot begin a sentence with \"' + repr(token) +
                             '\"')
        elif 'Define' == token.text:
            self._token_stream.push_back(token)
            return self.parse_definition(scope)
        node = Sentence([token])
        part_match = scope.new_matcher()
        if not part_match.next(token):
            self._token_stream.push_back(token)
            raise ParseError('Sentence not matched.', node)
        for token in self._token_stream:
            if isinstance(token, FirstToken):
                self._token_stream.push_back(token)
                if part_match.next():
                    node.append(self.parse_expression(scope))
                elif node.ends_with_dot() and part_match.has_end():
                    return node
                else:
                    raise ParseError('Sentence not matched.', node)
            elif isinstance(token, WordToken):
                if part_match.next(token):
                    node.append(token)
                elif node.ends_with_dot() and part_match.has_end():
                    self._token_stream.push_back(token)
                    return node
                else:
                    raise ParseError('Sentence not matched.', node)
            elif isinstance(token, PeriodToken):
                if part_match.has_end():
                    node.append(token)
                    return node
                else:
                    raise ParseError('Sentence not matched.', node)
            elif isinstance(token, ValueToken):
                if part_match.next():
                    node.append(Sentence([token]))
                else:
                    raise ParseError('Sentence not matched.', node)
            else:
                raise ValueError('Unknown Token Kind: {}'.format(type(token)))
        if isinstance(node[-1], Sentence) and part_match.has_end():
            return node
        raise ParseError('Sentence not matched.', node)
Example #2
0
    def parse_definition(self, outer_scope):
        """Parse a definition from the incomming tokens.

        This is technically a kind of expression, but there are a few special
        rules that may force it to become seperate. This is temporary as it
        is just the fastest way I can get this to work. I hope.

        'Define Function or variable name. to be Body. .'"""
        token = next(self._token_stream)
        if 'Define' != token.text:
            raise ParseError('Invalid start of definition: ' + str(token))
        node = Sentence(token)
        ptr = outer_scope.new_matcher()
        if not ptr.next(token):
            self._token_stream.push_back(item)
            raise ParseError('Sentence not matched.', node)
        inner_scope = None
        for item in self._token_stream:
            if isinstance(item, FirstToken):
                self._token_stream.push_back(item)
                if ptr.next():
                    if inner_scope is None:
                        signature = self.parse_signature()
                        node.append(signature)
                        inner_scope = outer_scope.new_define_scope(signature)
                    else:
                        node.append(self.parse_expression(inner_scope))
                elif node.ends_with_dot() and ptr.has_end():
                    return node
                else:
                    raise ParseError('Sentence not matched.', node)
            elif isinstance(item, WordToken):
                if ptr.next(item):
                    node.append(item)
                elif node.ends_with_dot() and ptr.has_end():
                    self._token_stream.push_back(item)
                    return node
                else:
                    raise ParseError('Sentence not matched.', node)
            elif isinstance(item, PeriodToken):
                if ptr.has_end():
                    node.append(item)
                    return node
                else:
                    raise ParseError('Sentence not matched.', node)
            elif isinstance(item, ValueToken):
                if ptr.next():
                    node.append(Sentence(item))
                else:
                    raise ParseError('Sentence not matched.', node)
            else:
                raise TypeError('Parser.parse_definition: Unexpected type' +
                                str(type(item)))
        if node.ends_with_dot() and ptr.has_end():
            return node
        raise ParseError('Sentence not matched.', node)
Example #3
0
 def test_ends_with_dot_period(self):
     has_period = Sentence(
         [FirstToken('Short'),
          WordToken('sentence'),
          PeriodToken()])
     self.assertTrue(has_period.ends_with_dot())
     no_period = Sentence([FirstToken('Word')])
     self.assertFalse(no_period.ends_with_dot())
     super_has_period = Sentence([FirstToken('Run'), has_period])
     self.assertTrue(super_has_period.ends_with_dot())
     super_no_period = Sentence([FirstToken('Run'), no_period])
     self.assertFalse(super_no_period.ends_with_dot())