Subversion Repositories programming

Rev

Rev 164 | Rev 166 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
161 ira 1
#!/usr/bin/env python
2
# Copyright: Ira W. Snyder
3
# Start Date: 2005-11-18
4
# End Date:
5
# License: Public Domain
6
#
7
# Changelog Follows:
8
#
9
# 2005-11-18
10
# * Just getting the basics in place, since we haven't been given
11
#   the whole description of the project yet.
12
#
13
 
14
# Check for <Python-2.3 compatibility (boolean values)
15
try:
16
  True, False
17
except NameError:
18
  (True, False) = (1, 0)
19
 
162 ira 20
import sys
163 ira 21
 
164 ira 22
class Queue:
23
    """Implements a basic FIFO queue"""
24
 
25
    def __init__(self):
26
        self.q = []
27
 
28
    def empty(self):
29
        """Empty the queue"""
30
        self.q = []
31
 
32
    def enqueue(self, elem):
33
        """Enqueue an element"""
34
        self.q.append(elem)
35
 
36
    def dequeue(self):
37
        """Get the object at the front of the queue"""
38
        elem = self.q[0]
39
        self.q = self.q[1:]
40
        return elem
41
 
162 ira 42
class RecursiveDescentParser:
161 ira 43
    def __init__(self):
162 ira 44
        self.__clear()
161 ira 45
 
46
    def __clear(self):
47
        self.str = ""   # the string of input to test
48
        self.strpos = 0 # the current position in str
49
 
50
    def __input_test_str(self):
162 ira 51
        self.str = raw_input("input str: ")
161 ira 52
 
53
    def main_menu(self):
54
 
55
        done = False
56
 
57
        while not done:
58
            print 'Menu:'
59
            print '========================================'
60
            print '1. Test a string'
61
            print '2. Quit'
62
            print
63
            s = raw_input('Choice >>> ')
64
            print
65
 
66
            if s == '1':
162 ira 67
                self.__clear()
161 ira 68
                self.__input_test_str()
69
                self.__test_str()
70
            elif s == '2':
71
                done = True
72
            else:
73
                print 'Bad Selection'
74
                print
75
 
162 ira 76
    def __test_str(self):
164 ira 77
        print 'Parsing: %s' % ((self.procE() and len(self.str) == self.strpos) and 'Completed' or 'Failed', )
163 ira 78
        print
161 ira 79
 
162 ira 80
    def procE(self):
81
        print 'procE(%s) ->' % (self.str[self.strpos:])
163 ira 82
 
164 ira 83
        # Catch the exception generated below if we don't have enough
84
        # input to 'look ahead'
85
        try:
86
            return self.procT() and self.procEprm()
87
        except IndexError:
88
            print 'Not enough input to continue, failed.'
89
            return False
162 ira 90
 
163 ira 91
    def procEprm(self):
92
        # Check empty str
93
        if self.strpos >= len(self.str):
94
            return True
95
 
96
        print 'procEprm(%s) ->' % (self.str[self.strpos:])
97
 
98
        # Check +
99
        if self.str[self.strpos] == '+':
100
            self.strpos += 1
101
            return self.procT() and self.procEprm()
102
 
103
        # Check -
104
        if self.str[self.strpos] == '-':
105
            self.strpos += 1
106
            return self.procT() and self.procEprm()
107
 
108
        # We accept empty str, so take it
109
        return True
110
 
162 ira 111
    def procT(self):
112
        print 'procT(%s) ->' % (self.str[self.strpos:])
113
 
164 ira 114
        return self.procP() and self.procTprm()
162 ira 115
 
163 ira 116
    def procTprm(self):
162 ira 117
        # Check empty str
118
        if self.strpos >= len(self.str):
119
            return True
120
 
163 ira 121
        print 'procTprm(%s) ->' % (self.str[self.strpos:])
162 ira 122
 
163 ira 123
        # Check *
124
        if self.str[self.strpos] == '*':
162 ira 125
            self.strpos += 1
164 ira 126
            return self.procP() and self.procTprm()
162 ira 127
 
163 ira 128
        # we accept empty str, so take it
129
        return True
130
 
164 ira 131
    def procP(self):
132
        print 'procP(%s) ->' % (self.str[self.strpos:])
133
 
134
        return self.procF() and self.procPprm()
135
 
136
    def procPprm(self):
137
        # Check empty str
138
        if self.strpos >= len(self.str):
139
            return True
140
 
141
        print 'procPprm(%s) -> ' % (self.str[self.strpos:])
142
 
143
        # check exp symbol
144
        if self.str[self.strpos] == '^':
145
            self.strpos += 1
146
            return self.procF() and self.procPprm()
147
 
148
        # we accept empty str, so take it
149
        return True
150
 
163 ira 151
    def procF(self):
152
        print 'procF(%s) ->' % (self.str[self.strpos:])
153
 
154
        # Check x
155
        if self.str[self.strpos] == 'x':
156
            self.strpos += 1
157
            return self.procV()
158
 
159
        # Check (E)
160
        if self.str[self.strpos] == '(':
161
            self.strpos += 1
162
 
163
            if self.procE():
164
                if self.str[self.strpos] == ')':
164 ira 165
                    self.strpos += 1
163 ira 166
                    return True
167
 
164 ira 168
                return False
169
 
163 ira 170
            return False
171
 
172
        # Must be a number
173
        return self.procN()
174
 
175
    def procN(self):
176
        print 'procN(%s) ->' % (self.str[self.strpos:])
177
 
164 ira 178
        if self.procD(): # we have one digit
179
            if self.procD(): # two digits
180
                return True
181
 
163 ira 182
            return True
183
 
162 ira 184
        return False
185
 
163 ira 186
    def procV(self):
187
        print 'procV(%s) ->' % (self.str[self.strpos:])
188
 
164 ira 189
        return self.procD()
163 ira 190
 
164 ira 191
    def procD(self):
192
        print 'procD(%s) ->' % (self.str[self.strpos:])
193
 
165 ira 194
        try:
195
            # Check if we are a single digit
196
            if self.str[self.strpos] in '0123456789':
197
                self.strpos += 1
198
                return True
199
        except IndexError: # ran out of input
200
            return False
164 ira 201
 
202
        return False
203
 
161 ira 204
if __name__ == '__main__':
162 ira 205
    rdp = RecursiveDescentParser()
206
    rdp.main_menu()
161 ira 207