1 module pegged.examples.json;
2 
3 import pegged.grammar;
4 
5 mixin(grammar(`
6 JSON:
7     JSONObject <  :'{' (Pair (:',' Pair)*)? :'}'
8     Pair       <  String :':' Value
9     Array      <  :'[' (Value (:',' Value)* )? :']'
10 
11     Value  <  String
12             / Number
13             / JSONObject
14             / Array
15             / True
16             / False
17             / Null
18     True   <- "true"
19     False  <- "false"
20     Null   <- "null"
21 
22     String <~ :doublequote Char* :doublequote
23     Char   <~ backslash doublequote
24             / backslash backslash
25             / backslash [bfnrt]
26             / backslash 'u' Hex Hex Hex Hex
27             / (!doublequote .)
28 
29     Number <~ '0'
30             / [1-9] Digit* ('.' Digit*)?
31     Digit  <- [0-9]
32     Hex    <- [0-9A-Fa-f]
33 `));
34 
35 unittest
36 {
37     enum example2 = `
38     {
39     "Number": 42,
40     "Decimal": 123.456,
41     "String": "abc",
42     "NullString": "",
43     "Escape": "\uAAAA\n\\Hello",
44     "Array" : [0,1,2],
45     "Array2": [0, [0,1,2], "abc"],
46     "Obj"   : { "Member":0, "Member":[0,1,2] },
47     "True"  : true,
48     "False" : false,
49     "Null"  : null,
50     "Empty" : {}
51     }`;
52 
53     auto example2Tree = JSON(example2);
54     assert(example2Tree.successful);
55     assert(example2Tree[0].children.length == 12);
56     assert(example2Tree[0][0][0].matches == ["Number"]);
57     assert(example2Tree[0][0][1].matches == ["42"]);
58 
59     enum example3 =
60         `{
61         "glossary": {
62             "title": "example glossary",
63             "GlossDiv": {
64                 "title": "S",
65                 "GlossList": {
66                     "GlossEntry": {
67                         "ID": "SGML",
68                         "SortAs": "SGML",
69                         "GlossTerm": "Standard Generalized Markup Language",
70                         "Acronym": "SGML",
71                         "Abbrev": "ISO 8879:1986",
72                         "GlossDef": {
73                             "para": "A meta-markup language, used to create markup languages such as DocBook.",
74                             "GlossSeeAlso": ["GML", "XML"]
75                         },
76                         "GlossSee": "markup"
77                     }
78                 }
79             }
80         }
81     }`;
82 
83     enum example4 =
84     `{"web-app": {
85     "servlet": [
86         {
87         "servlet-name": "cofaxCDS",
88         "servlet-class": "org.cofax.cds.CDSServlet",
89         "init-param": {
90             "configGlossary:installationAt": "Philadelphia, PA",
91             "configGlossary:adminEmail": "ksm@pobox.com",
92             "configGlossary:poweredBy": "Cofax",
93             "configGlossary:poweredByIcon": "/images/cofax.gif",
94             "configGlossary:staticPath": "/content/static",
95             "templateProcessorClass": "org.cofax.WysiwygTemplate",
96             "templateLoaderClass": "org.cofax.FilesTemplateLoader",
97             "templatePath": "templates",
98             "templateOverridePath": "",
99             "defaultListTemplate": "listTemplate.htm",
100             "defaultFileTemplate": "articleTemplate.htm",
101             "useJSP": false,
102             "jspListTemplate": "listTemplate.jsp",
103             "jspFileTemplate": "articleTemplate.jsp",
104             "cachePackageTagsTrack": 200,
105             "cachePackageTagsStore": 200,
106             "cachePackageTagsRefresh": 60,
107             "cacheTemplatesTrack": 100,
108             "cacheTemplatesStore": 50,
109             "cacheTemplatesRefresh": 15,
110             "cachePagesTrack": 200,
111             "cachePagesStore": 100,
112             "cachePagesRefresh": 10,
113             "cachePagesDirtyRead": 10,
114             "searchEngineListTemplate": "forSearchEnginesList.htm",
115             "searchEngineFileTemplate": "forSearchEngines.htm",
116             "searchEngineRobotsDb": "WEB-INF/robots.db",
117             "useDataStore": true,
118             "dataStoreClass": "org.cofax.SqlDataStore",
119             "redirectionClass": "org.cofax.SqlRedirection",
120             "dataStoreName": "cofax",
121             "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
122             "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
123             "dataStoreUser": "sa",
124             "dataStorePassword": "dataStoreTestQuery",
125             "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
126             "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
127             "dataStoreInitConns": 10,
128             "dataStoreMaxConns": 100,
129             "dataStoreConnUsageLimit": 100,
130             "dataStoreLogLevel": "debug",
131             "maxUrlLength": 500}},
132         {
133         "servlet-name": "cofaxEmail",
134         "servlet-class": "org.cofax.cds.EmailServlet",
135         "init-param": {
136         "mailHost": "mail1",
137         "mailHostOverride": "mail2"}},
138         {
139         "servlet-name": "cofaxAdmin",
140         "servlet-class": "org.cofax.cds.AdminServlet"},
141 
142         {
143         "servlet-name": "fileServlet",
144         "servlet-class": "org.cofax.cds.FileServlet"},
145         {
146         "servlet-name": "cofaxTools",
147         "servlet-class": "org.cofax.cms.CofaxToolsServlet",
148         "init-param": {
149             "templatePath": "toolstemplates/",
150             "log": 1,
151             "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
152             "logMaxSize": "",
153             "dataLog": 1,
154             "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
155             "dataLogMaxSize": "",
156             "removePageCache": "/content/admin/remove?cache=pages&id=",
157             "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
158             "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
159             "lookInContext": 1,
160             "adminGroupID": 4,
161             "betaServer": true}}],
162     "servlet-mapping": {
163         "cofaxCDS": "/",
164         "cofaxEmail": "/cofaxutil/aemail/*",
165         "cofaxAdmin": "/admin/*",
166         "fileServlet": "/static/*",
167         "cofaxTools": "/tools/*"},
168 
169     "taglib": {
170         "taglib-uri": "cofax.tld",
171         "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
172     `;
173 
174     assert(JSON(example3).successful);
175     assert(JSON(example4).successful);
176 }