I am trying to parse a line of from a Cisco config which has optional parameters. For some reason, the following code does not work unless I put in the optional parameter. It seems to read the next parameter after tag_server into nameif even if it is the literal "host".
#!/usr/local/bin/python
import sys
import string
import re
import os
import csv
import pyparsing
if __name__ == '__main__':
# Now to test pyparsing
from pyparsing import Literal, Word, alphanums, Optional, FollowedBy, ZeroOrMore, printables, MatchFirst
propval = Word(printables)
tag_server = propval.setResultsName("server_tag")
nameif = propval.setResultsName("if_name")
hostnm = propval.setResultsName("hostip")
ifhost = nameif + Literal('host').suppress()
HOST = Literal('host').suppress()
aaa_server = Literal('aaa-server').suppress()+tag_server+ Optional(nameif)+HOST+hostnm
#try:
test = aaa_server.parseString("aaa-server tacacs+ host 192.168.5.12 test timeout 3")
#except:
# test = None
if test:
print test
print test["if_name"]
else:
print "None found"
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What is the general format supposed to be for this line? I'm guessing something like:
aaa-server <server-name> [<nameif>] host <ip-address> <other stuff on the rest of the line>
What you've tripped over is that pyparsing does not look ahead in the grammar for literals, the same way that regexp's do. Since "host" is a word composed of printables, it looks to pyparsing like a perfectly valid nameif. Since you don't want to accept "host" as this name, you should define nameif as:
I am trying to parse a line of from a Cisco config which has optional parameters. For some reason, the following code does not work unless I put in the optional parameter. It seems to read the next parameter after tag_server into nameif even if it is the literal "host".
#!/usr/local/bin/python
import sys
import string
import re
import os
import csv
import pyparsing
if __name__ == '__main__':
# Now to test pyparsing
from pyparsing import Literal, Word, alphanums, Optional, FollowedBy, ZeroOrMore, printables, MatchFirst
propval = Word(printables)
tag_server = propval.setResultsName("server_tag")
nameif = propval.setResultsName("if_name")
hostnm = propval.setResultsName("hostip")
ifhost = nameif + Literal('host').suppress()
HOST = Literal('host').suppress()
aaa_server = Literal('aaa-server').suppress()+tag_server+ Optional(nameif)+HOST+hostnm
#try:
test = aaa_server.parseString("aaa-server tacacs+ host 192.168.5.12 test timeout 3")
#except:
# test = None
if test:
print test
print test["if_name"]
else:
print "None found"
Ray -
What is the general format supposed to be for this line? I'm guessing something like:
aaa-server <server-name> [<nameif>] host <ip-address> <other stuff on the rest of the line>
What you've tripped over is that pyparsing does not look ahead in the grammar for literals, the same way that regexp's do. Since "host" is a word composed of printables, it looks to pyparsing like a perfectly valid nameif. Since you don't want to accept "host" as this name, you should define nameif as:
nameif = (~HOST + propval).setResultsName("if_name")
(You'll have to move your declaration of HOST to the previous line or else Python will complain.)
-- Paul