Thread: [Pyparsing] Naming elements based on their predecessor
Brought to you by:
ptmcg
From: Joshua J. K. <jk...@sk...> - 2008-03-07 00:17:32
|
Now that I have your attention via that confusing subject line, here is what I'm trying to do. I read through the manual again...if what I'm describing is in there, it didn't jump out at me. In the MS SQL table dumps I'm parsing, there are lines such as these: exec sp_addextendedproperty N'MS_Description', N'The user and password table', N'user', N'dbo', N'table', N'auth_login' GO exec sp_addextendedproperty N'MS_Description', N'User name', N'user', N'dbo', N'table', N'auth_login', N'column', N'login' GO I guess you could say they are kind of a really messed up implementation of Python's keyword arguments. After the procedure call, you have lines of the format: N'Key' N'Value'... So, I have a Pyparsing expression that parses these nicely: ext_prop = (p.Combine(p.Keyword('exec') + p.Keyword('sp_addextendedproperty'), joinString=" ", adjacent=False) + p.delimitedList(p.Keyword('N').suppress() + p.QuotedString(quoteChar="'")) ) Combine that with: table_dump = (create_table.setResultsName('table_def') + p.Keyword('GO').suppress() + p.ZeroOrMore(ext_prop.setResultsName('ext_prop', listAllMatches=True) + p.Keyword('GO').suppress()) ) and create_data = table_dump.parseString(sql) for ep in create_data.ext_prop: print ep Gives me: ['exec sp_addextendedproperty', 'MS_Description', 'The user and password table', 'user', 'dbo', 'table', 'auth_login'] ['exec sp_addextendedproperty', 'MS_Description', 'User name', 'user', 'dbo', 'table', 'auth_login', 'column', 'login'] Nice. Now, I'd like to extend that in this way: Starting with the first "key" (in this case MS_Description) I'd like the follow value to have the name of that key, as if I had called setResultsName for it. Said another (hopefully clearer) way: When I do that above "for ep..." loop, I'd like to be able to: print ep.MS_Description #and get 'User name' print ep.table #and get auth_login print ep.column #and get login I'd check for ep.column first via hasattr, since it might not be there if it's parsing a call to set exteneded properties for a table. Is this at all doable without some major pyparsing hackery? Granted, I can just access by position in list, but I like the attribute accessors, as they look cleaner and are somewhat self documenting. Of course, I can always spell out the full procedure call, and manually name each value, but the less (and simpler) the code the better. j -- Joshua Kugler VOC/SigNet Provider (aka Web App Programmer) S&K Aerospace Alaska |
From: Paul M. <pa...@al...> - 2008-03-07 00:23:35
|
Joshua - You are the perfect straight-man! What you describe is exactly what the Dict class is for. Dict is something kind of unwieldy, so there is also a dictOf(key,value) helper method. I'm in the middle of some work at the moment, but check out the dict examples on the pyparsing wiki, or in the examples directory of your pyparsing distribution, or google for "pyparsing dict" to find any previous comments I've posted on it. -- Paul -----Original Message----- From: pyp...@li... [mailto:pyp...@li...] On Behalf Of Joshua J. Kugler Sent: Thursday, March 06, 2008 6:18 PM To: PyParsing User List Subject: [Pyparsing] Naming elements based on their predecessor Now that I have your attention via that confusing subject line, here is what I'm trying to do. I read through the manual again...if what I'm describing is in there, it didn't jump out at me. In the MS SQL table dumps I'm parsing, there are lines such as these: exec sp_addextendedproperty N'MS_Description', N'The user and password table', N'user', N'dbo', N'table', N'auth_login' GO exec sp_addextendedproperty N'MS_Description', N'User name', N'user', N'dbo', N'table', N'auth_login', N'column', N'login' GO I guess you could say they are kind of a really messed up implementation of Python's keyword arguments. After the procedure call, you have lines of the format: N'Key' N'Value'... So, I have a Pyparsing expression that parses these nicely: ext_prop = (p.Combine(p.Keyword('exec') + p.Keyword('sp_addextendedproperty'), joinString=" ", adjacent=False) + p.delimitedList(p.Keyword('N').suppress() + p.QuotedString(quoteChar="'")) ) Combine that with: table_dump = (create_table.setResultsName('table_def') + p.Keyword('GO').suppress() + p.ZeroOrMore(ext_prop.setResultsName('ext_prop', listAllMatches=True) + p.Keyword('GO').suppress()) ) and create_data = table_dump.parseString(sql) for ep in create_data.ext_prop: print ep Gives me: ['exec sp_addextendedproperty', 'MS_Description', 'The user and password table', 'user', 'dbo', 'table', 'auth_login'] ['exec sp_addextendedproperty', 'MS_Description', 'User name', 'user', 'dbo', 'table', 'auth_login', 'column', 'login'] Nice. Now, I'd like to extend that in this way: Starting with the first "key" (in this case MS_Description) I'd like the follow value to have the name of that key, as if I had called setResultsName for it. Said another (hopefully clearer) way: When I do that above "for ep..." loop, I'd like to be able to: print ep.MS_Description #and get 'User name' print ep.table #and get auth_login print ep.column #and get login I'd check for ep.column first via hasattr, since it might not be there if it's parsing a call to set exteneded properties for a table. Is this at all doable without some major pyparsing hackery? Granted, I can just access by position in list, but I like the attribute accessors, as they look cleaner and are somewhat self documenting. Of course, I can always spell out the full procedure call, and manually name each value, but the less (and simpler) the code the better. j -- Joshua Kugler VOC/SigNet Provider (aka Web App Programmer) S&K Aerospace Alaska ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Pyparsing-users mailing list Pyp...@li... https://lists.sourceforge.net/lists/listinfo/pyparsing-users |
From: Joshua J. K. <jk...@sk...> - 2008-03-07 01:08:58
|
On Thu, 2008-03-06 at 18:23 -0600, Paul McGuire wrote: > You are the perfect straight-man! Uh, thanks? :) > What you describe is exactly what the Dict class is for. Dict is something > kind of unwieldy, so there is also a dictOf(key,value) helper method. Ah...spiffy. OK, so here's what I came up with: ext_prop = (p.Combine(p.Keyword('exec') + p.Keyword('sp_addextendedproperty'), joinString=" ", adjacent=False) + p.delimitedList(p.Dict(p.Group(p.Keyword('N').suppress() + p.QuotedString(quoteChar="'") + p.Literal(',').suppress() + p.Keyword('N').suppress() + p.QuotedString(quoteChar="'")))) ) And it seems to work just fine. Noticed something interesting: on a parsing object, an unknown attribute (such as 'asdfasdfsadf') will return '' (an empty string). Is this intended behavior? It makes testing for attributes via hasattr impossible. I can always test for an empty string, of course, but I'd rather use exceptions and catch an AttributeError than an if/then block to see if the string is non-emtpy. But that's just me. Anyway, thanks for the pointers. You've been a *huge* help. j -- Joshua Kugler VOC/SigNet Provider (aka Web App Programmer) S&K Aerospace Alaska |
From: Paul M. <pa...@al...> - 2008-03-07 01:19:37
|
>>>> Noticed something interesting: on a parsing object, an unknown attribute (such as 'asdfasdfsadf') will return '' (an empty string). Is this intended behavior? It makes testing for attributes via hasattr impossible. I can always test for an empty string, of course, but I'd rather use exceptions and catch an AttributeError than an if/then block to see if the string is non-emtpy. >>>> To test for the existence of an attribute: - if 'alsfjlsjafs' in results: - if results.alkjasdlfjslf == '': or if results.laksjdfljsd: # evaluating to '' is a boolean false value - results["sldflsjf"] will raise an exception if no such attribute -- Paul |
From: Joshua J. K. <jk...@sk...> - 2008-03-07 01:29:37
|
On Thu, 2008-03-06 at 19:19 -0600, Paul McGuire wrote: > >>>> > Noticed something interesting: on a parsing object, an unknown attribute > (such as 'asdfasdfsadf') will return '' (an empty string). Is this intended > behavior? It makes testing for attributes via hasattr impossible. I can > always test for an empty string, of course, but I'd rather use exceptions > and catch an AttributeError than an if/then block to see if the string is > non-emtpy. > >>>> > > To test for the existence of an attribute: > - if 'alsfjlsjafs' in results: > - if results.alkjasdlfjslf == '': > or if results.laksjdfljsd: # evaluating to '' is a boolean false value > - results["sldflsjf"] will raise an exception if no such attribute Right, I figured that out (testing on the empty value anyway), but it surprised me that an invalid attribute didn't raise an exception. Thanks again for all your help. j -- Joshua Kugler VOC/SigNet Provider (aka Web App Programmer) S&K Aerospace Alaska |