*sigh* I just read the documentation more carefully and found the difference between the <br>
| operator and the ^ operator. <br>
<br>
Input - <br>
<br>
j = { line = { foo = 10 bar = 20 } }<br>
<br>
New code<br>
<br>
sel = pp.Forward()<br>
values = ((pp.Word(pp.printables) + pp.Suppress(&quot;=&quot;) + pp.Word(pp.printables)) ^ sel)<br>
sel &lt;&lt; (pp.Word(pp.printables) + pp.Suppress(&quot;=&quot;) + pp.Suppress(&quot;{&quot;) + pp.OneOrMore(values) + pp.Suppress(&quot;}&quot;))<br>
<br>
Output - <br>
<br>
(['j', 'line', 'foo', '10', 'bar', '20'], {})<br>
<br>
My apologies for the deluge. <br>
<br>
Regards, <br>
<br>
Liam Clarke<br><br><div><span class="gmail_quote">On 7/24/05, <b class="gmail_sendername">Liam Clarke</b> &lt;<a href="mailto:cyresse@gmail.com">cyresse@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hmmm... just a quick update, I've been poking around and I'm obviously making some error of logic. <br>
<br>
Given a line - <br>
<br>
&nbsp;f = &quot;j = { line = { foo = 10 bar = 20 } }&quot;<br>
<br>
And given the following code - <br>
<br>
select = pp.Forward()<br>select &lt;&lt; <br>
pp.Word(pp.printables) + pp.Suppress(&quot;=&quot;) + pp.Suppress(&quot;{&quot;) + <br>
pp.OneOrMore( (pp.Word(pp.printables) + pp.Suppress(&quot;=&quot;) + <br>
pp.Word(pp.printables) ) | select ) + pp.Suppress(&quot;}&quot;)<br>
<br>
sel.parseString(f) gives - <br>
<br>
(['j', 'line', '{', 'foo', '10', 'bar', '20'], {})<br>
<br>
So I've got a bracket sneaking through there. Argh. My brain hurts. <br>
<br>
Is the | operator an exclusive or? <br>
<br>
Befuddled, <br><span class="sg">
<br>
Liam Clarke</span><div><span class="e" id="q_10543e5b14451113_2"><br>
<br><div><span class="gmail_quote">On 7/23/05, <b class="gmail_sendername">Liam Clarke</b> &lt;<a href="mailto:cyresse@gmail.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">cyresse@gmail.com</a>
&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Howdy, <br>
<br>
I've attempted to follow your lead and have started from scratch, I
could just copy and paste your solution (which works pretty well), but
I want to understand what I'm doing *grin*<br>
<br>
However, I've been hitting a couple of ruts in the path to
enlightenment. Is there a way to tell pyparsing that to treat specific
escaped characters as just a slash followed by a letter? For the time
being I've converted all backslashes to forwardslashes, as it was
choking on \a in a file path.<br>
<br>
But my latest hitch, takes this form (apologies for large traceback)<br>
<br>
Traceback (most recent call last):<br>
&nbsp; File &quot;&lt;interactive input&gt;&quot;, line 1, in ?<br>
&nbsp; File &quot;parse.py&quot;, line 336, in parse<br>
&nbsp;&nbsp;&nbsp; parsedEntries = dicts.parseString(test_data)<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 616, in parseString<br>
&nbsp;&nbsp;&nbsp; loc, tokens = self.parse( instring.expandtabs(), 0 )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 558, in parse<br>
&nbsp;&nbsp;&nbsp; loc,tokens = self.parseImpl( instring, loc, doActions )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 1518, in parseImpl<br>
&nbsp;&nbsp;&nbsp; return self.expr.parse( instring, loc, doActions )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 558, in parse<br>
&nbsp;&nbsp;&nbsp; loc,tokens = self.parseImpl( instring, loc, doActions )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 1367, in parseImpl<br>
&nbsp;&nbsp;&nbsp; loc, exprtokens = e.parse( instring, loc, doActions )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 558, in parse<br>
&nbsp;&nbsp;&nbsp; loc,tokens = self.parseImpl( instring, loc, doActions )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 1518, in parseImpl<br>
&nbsp;&nbsp;&nbsp; return self.expr.parse( instring, loc, doActions )<br>
&nbsp; File &quot;c:\python24\Lib\site-packages\pyparsing.py&quot;, line 560, in parse<br>
&nbsp;&nbsp;&nbsp; raise ParseException, ( instring, len(instring), self.errmsg, self )<br>
<br>
ParseException: Expected &quot;}&quot; (at char 9909), (line:325, col:5)<br>
<br>
The offending code can be found here (includes the data) - <a href="http://www.rafb.net/paste/results/L560wx80.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">http://www.rafb.net/paste/results/L560wx80.html
</a><br>
<br>
It's like pyparsing isn't recognising a lot of my &quot;}&quot;'s, as if I add
another one, it throws the same error, same for adding another two...<br>
<br>
No doubt I've done something silly, but any help in finding the tragic
flaw would be much appreciated. I need to get a parsingResults object
out so I can learn how to work with the basic structure!<br>
<br>
Much regards,<br>
<br>
Liam Clarke<div><span><br><br><div><span class="gmail_quote">On 7/21/05, <b class="gmail_sendername">Paul McGuire</b> &lt;<a href="mailto:paul@alanweberassociates.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">

paul@alanweberassociates.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Liam, Kent, and Danny -<br><br>It sure looks like pyparsing is taking on a life of its own!&nbsp;&nbsp;I can see I no<br>longer am the only one pitching pyparsing at some of these applications!<br><br>Yes, Liam, it is possible to create dictionary-like objects, that is,
<br>ParseResults objects that have named values in them.&nbsp;&nbsp;I looked into your<br>application, and the nested assignments seem very similar to a ConfigParse<br>type of structure.&nbsp;&nbsp;Here is a pyparsing version that handles the test data
<br>in your original post (I kept Danny Yoo's recursive list values, and added<br>recursive dictionary entries):<br><br>--------------------------<br>import pyparsing as pp<br><br>listValue = pp.Forward()<br>listSeq = pp.Suppress


('{') + pp.Group(pp.ZeroOrMore(listValue)) +<br>pp.Suppress('}')<br>listValue &lt;&lt; ( pp.dblQuotedString.setParseAction(pp.removeQuotes) |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pp.Word(pp.alphanums)
| listSeq )<br><br>keyName = pp.Word( pp.alphas )<br><br>entries = pp.Forward()<br>entrySeq = pp.Suppress('{') + pp.Group(pp.OneOrMore(entries)) +<br>pp.Suppress('}')<br>entries &lt;&lt; pp.Dict(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pp.OneOrMore


(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pp.Group(
keyName + pp.Suppress('=') + (entrySeq |<br>listValue) ) ) )<br>--------------------------<br><br><br>Dict is one of the most confusing classes to use, and there are some<br>examples in the examples directory that comes with pyparsing (see
<br>dictExample2.py), but it is still tricky.&nbsp;&nbsp;Here is some code to access your<br>input test data, repeated here for easy reference:<br><br>--------------------------<br>testdata = &quot;&quot;&quot;\<br>country = {<br>

tag = ENG
<br>ai = {<br>flags = { }<br>combat = { DAU FRA ORL PRO }<br>continent = { }<br>area = { }<br>region = { &quot;British Isles&quot; &quot;NorthSeaSea&quot; &quot;ECAtlanticSea&quot; &quot;NAtlanticSea&quot;<br>&quot;TagoSea&quot; &quot;WCAtlanticSea&quot; }
<br>war = 60<br>ferocity = no<br>}<br>}<br>&quot;&quot;&quot;<br>parsedEntries = entries.parseString(testdata)<br><br>def dumpEntries(dct,depth=0):<br>&nbsp;&nbsp;&nbsp;&nbsp;keys = dct.keys()<br>&nbsp;&nbsp;&nbsp;&nbsp;keys.sort()<br>&nbsp;&nbsp;&nbsp;&nbsp;for k in keys:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print ('&nbsp;&nbsp;'*depth) + '- ' + k + ':',
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if isinstance(dct[k],pp.ParseResults):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if dct[k][0].keys():<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dumpEntries(dct[k][0],depth+1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print dct[k][0]<br>


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print dct[k]<br><br>dumpEntries( parsedEntries )<br><br>print<br>print parsedEntries.country[0].tag<br>print parsedEntries.country[0].ai[0].war<br>print parsedEntries.country[0].ai[0].ferocity
<br>--------------------------<br><br>This will print out:<br><br>--------------------------<br>- country:<br>&nbsp;&nbsp;- ai:<br>&nbsp;&nbsp;&nbsp;&nbsp;- area: []<br>&nbsp;&nbsp;&nbsp;&nbsp;- combat: ['DAU', 'FRA', 'ORL', 'PRO']<br>&nbsp;&nbsp;&nbsp;&nbsp;- continent: []<br>&nbsp;&nbsp;&nbsp;&nbsp;- ferocity: no
<br>&nbsp;&nbsp;&nbsp;&nbsp;- flags: []<br>&nbsp;&nbsp;&nbsp;&nbsp;- region: ['British Isles', 'NorthSeaSea', 'ECAtlanticSea',<br>'NAtlanticSea', 'TagoSea', 'WCAtlanticSea']<br>&nbsp;&nbsp;&nbsp;&nbsp;- war: 60<br>&nbsp;&nbsp;- tag: ENG<br><br>ENG<br>60<br>No<br>--------------------------<br>


<br>But I really dislike having to dereference those nested values using the<br>0'th element.&nbsp;&nbsp;So I'm going to fix pyparsing so that in the next release,<br>you'll be able to reference the sub-elements as:<br><br>print parsedEntries.country.tag


<br>print parsedEntries.country.ai.war<br>print parsedEntries.country.ai.ferocity<br><br>This *may* break some existing code, but Dict is not heavily used, based on<br>feedback from users, and this may make it more useful in general, especially
<br>when data parses into nested Dict's.<br><br>Hope this sheds more light than confusion!<br>-- Paul McGuire<br><br>_______________________________________________<br>Tutor maillist&nbsp;&nbsp;-&nbsp;&nbsp;<a href="mailto:Tutor@python.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">


Tutor@python.org</a><br><a href="http://mail.python.org/mailman/listinfo/tutor" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">http://mail.python.org/mailman/listinfo/tutor</a><br></blockquote></div>

<br><br clear="all"><br></span></div><span>-- <br>'There is only one basic human right, and that is to do as you damn well please.
<br>And with it comes the only basic human duty, to take the consequences.'

</span></blockquote></div><br><br clear="all"><br>-- <br>'There is only one basic human right, and that is to do as you damn well please.<br>And with it comes the only basic human duty, to take the consequences.'

</span></div></blockquote></div><br><br clear="all"><br>-- <br>'There is only one basic human right, and that is to do as you damn well please.<br>And with it comes the only basic human duty, to take the consequences.'