I'm trying to write pyparsing rules to parse a document that's similar to JSON.
My document looks like this:
s = {
id = "DEB36287-8871-4378-8805-B54CC5EED3C0",
internalName = "1a. Vintage Glow",
title = "1a. Vintage Glow",
type = "Develop",
value = {
settings = {
AutoLateralCA = 0,
Blacks2012 = -6,
BlueHue = 0,
BlueSaturation = 0,
CameraProfile = "Embedded",
ChromaticAberrationB = 0,
ChromaticAberrationR = 0,
Clarity2012 = 0,
Contrast2012 = 0,
ConvertToGrayscale = false,
CropConstrainToWarp = 0,
Defringe = 0,
DefringeGreenAmount = 0,
DefringeGreenHueHi = 60,
DefringeGreenHueLo = 40,
DefringePurpleAmount = 0,
DefringePurpleHueHi = 70,
DefringePurpleHueLo = 30,
Dehaze = 0,
EnableCalibration = true,
EnableColorAdjustments = true,
EnableDetail = true,
EnableEffects = true,
EnableLensCorrections = true,
EnableSplitToning = true,
GrainAmount = 30,
GrainFrequency = 50,
GrainSize = 25,
GreenHue = 0,
GreenSaturation = 0,
Highlights2012 = 45,
HueAdjustmentAqua = 0,
HueAdjustmentBlue = 0,
HueAdjustmentGreen = 0,
HueAdjustmentMagenta = 0,
HueAdjustmentOrange = 0,
HueAdjustmentPurple = 0,
HueAdjustmentRed = 0,
HueAdjustmentYellow = 0,
LensManualDistortionAmount = 0,
LensProfileEnable = 0,
LensProfileSetup = "LensDefaults",
LuminanceAdjustmentAqua = 0,
LuminanceAdjustmentBlue = 0,
LuminanceAdjustmentGreen = 0,
LuminanceAdjustmentMagenta = 0,
LuminanceAdjustmentOrange = 0,
LuminanceAdjustmentPurple = 0,
LuminanceAdjustmentRed = -3,
LuminanceAdjustmentYellow = 0,
ParametricDarks = 0,
ParametricHighlightSplit = 75,
ParametricHighlights = 0,
ParametricLights = 0,
ParametricMidtoneSplit = 50,
ParametricShadowSplit = 25,
ParametricShadows = 0,
PostCropVignetteAmount = 0,
PostCropVignetteFeather = 50,
PostCropVignetteHighlightContrast = 0,
PostCropVignetteMidpoint = 50,
PostCropVignetteRoundness = 0,
PostCropVignetteStyle = 1,
ProcessVersion = "6.7",
RedHue = 0,
RedSaturation = 0,
Saturation = 0,
SaturationAdjustmentAqua = 0,
SaturationAdjustmentBlue = 0,
SaturationAdjustmentGreen = 0,
SaturationAdjustmentMagenta = 0,
SaturationAdjustmentOrange = 0,
SaturationAdjustmentPurple = 0,
SaturationAdjustmentRed = 0,
SaturationAdjustmentYellow = 0,
ShadowTint = 0,
Shadows2012 = 0,
SharpenDetail = 25,
SharpenEdgeMasking = 0,
SharpenRadius = 1,
Sharpness = 0,
SplitToningBalance = -32,
SplitToningHighlightHue = 50,
SplitToningHighlightSaturation = 6,
SplitToningShadowHue = 0,
SplitToningShadowSaturation = 0,
ToneCurveName2012 = "Custom",
Vibrance = 0,
VignetteAmount = 0,
VignetteMidpoint = 50,
Whites2012 = -70,
},
uuid = "59A86241-054F-4AE0-8C14-188A3038749B",
},
version = 0,
}
My rules look like this:
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda x: float(x[0]))
integer = Regex(r"[+-]?\d+").setParseAction(lambda x: int(x[0]))
quotedString.setParseAction(removeQuotes)
key = Word(alphanums)
value = Forward() #this tells pyparsing that values can be recursive
eq,leftBrace,rightBrace = map(Suppress, "={}")
entry = Group(key + eq + value + ZeroOrMore(Suppress(','))) #this is the basic name-value pair
struct = Dict(leftBrace + ZeroOrMore(entry) + rightBrace) #we will turn the output into a Dictionary
value << (struct | quotedString | real | integer)
I'm invoking pyparser as follows:
result = Dict(OneOrMore(entry)).parseString(data)
I'm getting the following error on line 6:
pyparsing.ParseException: Expected {Dict:({{Suppress:("{") [Group:({{W:(ABCD...) Suppress:("=") : ...} [Suppress:(",")]...})]...} Suppress:("}")}) | quotedString using single or double quotes | Re:('[+-]?\\d+\\.\\d*') | Re:('[+-]?\\d+')}, found 'v' (at char 201), (line:6, col:13)
Python version: 3.9.5 pyparsing version: 2.4.7 OS: Mac OS X 11.4 Platform: MacBook Air (M1, 2020)
I'm hoping someone can point me in the right direction for a fix.
EDIT: Final solution on the off-chance it helps someone else:
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda x: float(x[0]))
integer = Regex(r"[+-]?\d+").setParseAction(lambda x: int(x[0]))
booleanLiteral = oneOf("true false", asKeyword=True).setParseAction(lambda x: x[0] == "true")
eq,leftBrace,rightBrace = map(Suppress, "={}")
value = Forward()
key = Word(alphanums)
pair = Group(key + eq + value)
struct = (Dict(leftBrace + ZeroOrMore(pair) + rightBrace) | (leftBrace + ZeroOrMore(value) + rightBrace))
value << Group((dblQuotedString | struct | real | integer | booleanLiteral) + ZeroOrMore(Suppress(',')))
return Dict(pair).parseString(data).asDict()