# $Id: test_kjParseBuild.py,v 1.4 2002/05/11 02:59:05 richard Exp $ import unittest, os, shutil, time, sys from gadfly.kjParseBuild import * from gadfly import kjParseBuild, kjParser class test_kjParseBuild(unittest.TestCase): def test(self): def echo(x): return x # simple grammar stolen from a text LD0 = kjParser.LexDictionary() id = LD0.terminal("id","id",echo) plus = LD0.punctuation("+") star = LD0.punctuation("*") oppar = LD0.punctuation("(") clpar = LD0.punctuation(")") equals = LD0.punctuation("=") E = kjParser.nonterminal("E") T = kjParser.nonterminal("T") Tp = kjParser.nonterminal("Tp") Ep = kjParser.nonterminal("Ep") F = kjParser.nonterminal("F") rule1 = kjParser.ParseRule( E, [ T, Ep ] ) rule2 = kjParser.ParseRule( Ep, [ plus, T, Ep ] ) rule3 = kjParser.ParseRule( Ep, [ ] ) rule4 = kjParser.ParseRule( T, [ F, Tp ] ) rule5 = kjParser.ParseRule( Tp, [ star, F, Tp ] ) rule6 = kjParser.ParseRule( Tp, [ ] ) rule7 = kjParser.ParseRule( F, [ oppar, E, clpar ] ) rule8 = kjParser.ParseRule( F, [ id ] ) rl0 = [ rule1, rule2, rule3, rule4, rule5, rule6, rule7,rule8] rs0 = kjParseBuild.Ruleset(E, rl0) rs0.compFirst() Firstpairs = kjSet.GetPairs(rs0.First) rs0.compFollow() Followpairs = kjSet.GetPairs(rs0.Follow) rs0.compSLRNFA() NFA0 = rs0.SLRNFA rs0.compDFA() rs0.SLRFixDFA() DFA0 = rs0.DFA class dummy: pass ttt0 = dummy() ttt0.STRING = " id + id * id " #ttt.List = kjParser.LexList(LD0, ttt0.STRING) ttt0.Stream = kjParser.LexStringWalker(ttt0.STRING, LD0) ttt0.Stack = [] #{-1:0}# Walkers.SimpleStack() ttt0.ParseObj = kjParser.ParserObj(rl0, ttt0.Stream, DFA0, ttt0. Stack, 1) ttt0.RESULT = ttt0.ParseObj.GO() #ttt0.Stack.Dump(10) # an even simpler grammar S = kjParser.nonterminal("S") M = kjParser.nonterminal("M") A = kjParser.nonterminal("A") rr1 = kjParser.ParseRule( S, [M] ) #rr2 = kjParser.ParseRule( A, [A, plus, M]) #rr3 = kjParser.ParseRule( A, [M], echo) #rr4 = kjParser.ParseRule( M, [M, star, M]) rr5 = kjParser.ParseRule( M, [oppar, M, clpar]) rr6 = kjParser.ParseRule( M, [id]) rl1 = [rr1,rr5,rr6] rs1 = kjParseBuild.Ruleset(S, rl1) rs1.compFirst() rs1.compFollow() rs1.compSLRNFA() rs1.compDFA() rs1.SLRFixDFA() DFA1 = rs1.DFA ttt1=dummy() # def TESTDFA1( STRING , DOREDUCTIONS = 1): # return TESTDFA( STRING, ttt1, DFA1, rl1, DOREDUCTIONS ) X = kjParser.nonterminal("X") Y = kjParser.nonterminal("Y") RX = kjParser.ParseRule( X, [ oppar, Y, clpar ] ) RY = kjParser.ParseRule( Y, [] ) rl2 = [RX,RY] rs2 = kjParseBuild.Ruleset(X, rl2) rs2.compFirst() rs2.compFollow() rs2.compSLRNFA() rs2.compDFA() rs2.SLRFixDFA() DFA2 = rs2.DFA ttt2 = dummy() # def TESTDFA2( STRING, DOREDUCTIONS = 1): # return TESTDFA( STRING, ttt2, DFA2, rl2, DOREDUCTIONS ) # the following grammar should fail to be slr # (Aho,Ullman p. 213) S = kjParser.nonterminal("S") L = kjParser.nonterminal("L") R = kjParser.nonterminal("R") RS1 = kjParser.ParseRule( S, [L, equals, R] ) RS2 = kjParser.ParseRule( S, [R], echo ) RL1 = kjParser.ParseRule( L, [star, R]) RL2 = kjParser.ParseRule( L, [id]) RR1 = kjParser.ParseRule( R, [L] ) rs3 = kjParseBuild.Ruleset(S, [RS1,RS2,RL1,RL2,RR1]) rs3.compFirst() rs3.compFollow() rs3.compSLRNFA() rs3.compDFA() #rs3.SLRFixDFA() # should fail and does. # testing RULEGRAM ObjG = NullCGrammar() ObjG.Addterm("id","id",echo) ObjG.Nonterms("T E Ep F Tp") ObjG.Keywords("begin end") ObjG.punct("+*()") ObjG.comments(["--.*\n"]) # PROBLEM WITH COMMENTS??? Rulestr = """ ## what a silly grammar! T :: @R One :: T >> begin E end @R Three :: E >> @R Two :: E >> E + T @R Four :: E >> ( T ) """ RL = RULEGRAM.DoParse1( Rulestr, ObjG ) class test_Build(unittest.TestCase): ''' test generation of the grammar ''' MARSHALFILE = "SQLTEST_mar" def test(self): #set this to automatically rebuild the grammar. SELECTRULES = """ ## highest level for select statement (not select for update) select-statement :: @R selectR :: select-statement >> SELECT from-clause where-clause group-by-clause having-clause ## generalized to allow null from clause eg: select 2+2 @R fromNull :: from-clause >> @R fromFull :: from-clause >> FROM @R whereNull :: where-clause >> @R whereFull :: where-clause >> WHERE @R groupNull :: group-by-clause >> @R groupFull :: group-by-clause >> GROUP BY @R havingNull :: having-clause >> @R havingFull :: having-clause >> HAVING @R unionNull :: union-clause >> @R unionFull :: union-clause >> UNION """ SELECTNONTERMS = """ select-statement all-distinct select-list table-reference-list where-clause group-by-clause having-clause union-clause maybe-order-by search-condition column-list maybe-all order-by-clause column-name from-clause """ # of these the following need resolution # (select-list) (table-reference-list) # (search-condition) order-by-clause (column-name) SELECTKEYWORDS = """ SELECT FROM WHERE GROUP BY HAVING UNION DISTINCT ALL AS """ SQLG = kjParseBuild.NullCGrammar() SQLG.SetCaseSensitivity(0) SQLG.Keywords(SELECTKEYWORDS) SQLG.Nonterms(SELECTNONTERMS) # no comments yet SQLG.Declarerules(SELECTRULES) SQLG.Compile() outfile = open(self.MARSHALFILE+'.py', "w") SQLG.MarshalDump(outfile) outfile.close() SQLG2 = kjParser.UnMarshalGram(self.MARSHALFILE) def tearDown(self): filename = self.MARSHALFILE+'.py' if os.path.exists(filename): os.remove(filename) if os.path.exists(filename+'c'): os.remove(filename+'c') if os.path.exists(filename+'o'): os.remove(filename+'o') def suite(): l = [ unittest.makeSuite(test_kjParseBuild), unittest.makeSuite(test_Build), ] return unittest.TestSuite(l) if __name__ == '__main__': runner = unittest.TextTestRunner() runner.run(suite()) # # $Log: test_kjParseBuild.py,v $ # Revision 1.4 2002/05/11 02:59:05 richard # Added info into module docstrings. # Fixed docco of kwParsing to reflect new grammar "marshalling". # Fixed bug in gadfly.open - most likely introduced during sql loading # re-work (though looking back at the diff from back then, I can't see how it # wasn't different before, but it musta been ;) # A buncha new unit test stuff. # # Revision 1.3 2002/05/08 00:49:01 anthonybaxter # El Grande Grande reindente! Ran reindent.py over the whole thing. # Gosh, what a lot of checkins. Tests still pass with 2.1 and 2.2. # # Revision 1.2 2002/05/06 23:27:10 richard # . made the installation docco easier to find # . fixed a "select *" test - column ordering is different for py 2.2 # . some cleanup in gadfly/kjParseBuild.py # . made the test modules runnable (remembering that run_tests can take a # name argument to run a single module) # . fixed the module name in gadfly/kjParser.py # #