3

I am trying to use pyparsing to parse a configuration file of following form

x = "/user/test"
y = 3

Here is my code snippet

ParserElement.defaultWhitespaceChars = (" \t")
END = StringEnd()
NL = LineEnd().suppress()
assignment = Literal('=')

key_str = CharsNotIn("=")
value_str = Group(~assignment + restOfLine)

line = Group(key_str + assignment + value_str)
lines = ZeroOrMore(line)
lines.ignore(NL)

text = """
y = 3
x = 2
"""

The output that I get from parseFile tells me it is parsing the first line only. Can anybody please help me find out what I am doing wrong?

3
  • Would you be averse to using a library that can already parse files that look sort of like this? For example pypi.python.org/pypi/configobj Commented May 9, 2013 at 17:43
  • Thank you for your input.There are additional parsing work I am doing (e.g. parsing of a scheduler log, some script files etc). In that context I am trying to get a better understanding of pyparsing for last few weeks. I consider myself a novice in pyparsing area so wanted to get some pointers about what I did wrong here. Commented May 9, 2013 at 17:51
  • @AbhijitBhattacharya - search SO for other questions/answers with the pyparsing tag. You can also visit the wiki at pyparsing.wikispace.com, and read through the Discussion tab on the wiki Home page. Commented May 10, 2013 at 13:41

1 Answer 1

2

It looks like you are on the right track. Maybe you are doing something wrong when you acutally pass the text to the grammar. Adding the following line in your code

print lines.parseString(text)

Gives the expected output

[['y ', '=', [' 3']], ['x ', '=', [' 2']]]

As an aside, normally you don't want to keep the whitespace when parsing. The tokens are usually the only thing that matters. This is how I would parse your example:

EOL = LineEnd().suppress()
EQ  = Literal("=").suppress()
val = Word(alphanums)
line = Group(val('key') + EQ + val('val') + EOL)
grammar = OneOrMore(line)

for x in grammar.parseString(text):
    print x.dump()

The output in this case is much nicer

['y', '3']
- key: y
- val: 3
['x', '2']
- key: x
- val: 2
Sign up to request clarification or add additional context in comments.

7 Comments

No problem, and welcome to Stack Overflow! Typically the protocol is to upvote useful answers and "accept" an answer that solves your problem.
I've updated the answer to show a different approach at the grammar.
I accepted your answer. As for the upvote, I guess there is something called "reputation" for newcomers. Without that it doen't allow upvoting.
@AbhijitBhattacharya I didn't know there was a rep limit for upvoting your own question's answers. According to the FAQ, stackoverflow.com/faq#reputation, you'll need at least 15 rep to do so... looks like you're halfway there!
Try naming it "line*" - the trailing asterisk is a flag to pyparsing to keep all values, not just the last one; it is a shorthand for calling setResultsName with listAllMatches=True. Also, I overlooked one other point - the original question also had a RHS value of a quoted string as one of the examples. You can accommodate this by adding | quotedString to the definition of val.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.