scanner.go 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. package candiedyaml
  13. import (
  14. "bytes"
  15. )
  16. /*
  17. * Introduction
  18. * ************
  19. *
  20. * The following notes assume that you are familiar with the YAML specification
  21. * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
  22. * some cases we are less restrictive that it requires.
  23. *
  24. * The process of transforming a YAML stream into a sequence of events is
  25. * divided on two steps: Scanning and Parsing.
  26. *
  27. * The Scanner transforms the input stream into a sequence of tokens, while the
  28. * parser transform the sequence of tokens produced by the Scanner into a
  29. * sequence of parsing events.
  30. *
  31. * The Scanner is rather clever and complicated. The Parser, on the contrary,
  32. * is a straightforward implementation of a recursive-descendant parser (or,
  33. * LL(1) parser, as it is usually called).
  34. *
  35. * Actually there are two issues of Scanning that might be called "clever", the
  36. * rest is quite straightforward. The issues are "block collection start" and
  37. * "simple keys". Both issues are explained below in details.
  38. *
  39. * Here the Scanning step is explained and implemented. We start with the list
  40. * of all the tokens produced by the Scanner together with short descriptions.
  41. *
  42. * Now, tokens:
  43. *
  44. * STREAM-START(encoding) # The stream start.
  45. * STREAM-END # The stream end.
  46. * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
  47. * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
  48. * DOCUMENT-START # '---'
  49. * DOCUMENT-END # '...'
  50. * BLOCK-SEQUENCE-START # Indentation increase denoting a block
  51. * BLOCK-MAPPING-START # sequence or a block mapping.
  52. * BLOCK-END # Indentation decrease.
  53. * FLOW-SEQUENCE-START # '['
  54. * FLOW-SEQUENCE-END # ']'
  55. * BLOCK-SEQUENCE-START # '{'
  56. * BLOCK-SEQUENCE-END # '}'
  57. * BLOCK-ENTRY # '-'
  58. * FLOW-ENTRY # ','
  59. * KEY # '?' or nothing (simple keys).
  60. * VALUE # ':'
  61. * ALIAS(anchor) # '*anchor'
  62. * ANCHOR(anchor) # '&anchor'
  63. * TAG(handle,suffix) # '!handle!suffix'
  64. * SCALAR(value,style) # A scalar.
  65. *
  66. * The following two tokens are "virtual" tokens denoting the beginning and the
  67. * end of the stream:
  68. *
  69. * STREAM-START(encoding)
  70. * STREAM-END
  71. *
  72. * We pass the information about the input stream encoding with the
  73. * STREAM-START token.
  74. *
  75. * The next two tokens are responsible for tags:
  76. *
  77. * VERSION-DIRECTIVE(major,minor)
  78. * TAG-DIRECTIVE(handle,prefix)
  79. *
  80. * Example:
  81. *
  82. * %YAML 1.1
  83. * %TAG ! !foo
  84. * %TAG !yaml! tag:yaml.org,2002:
  85. * ---
  86. *
  87. * The correspoding sequence of tokens:
  88. *
  89. * STREAM-START(utf-8)
  90. * VERSION-DIRECTIVE(1,1)
  91. * TAG-DIRECTIVE("!","!foo")
  92. * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
  93. * DOCUMENT-START
  94. * STREAM-END
  95. *
  96. * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
  97. * line.
  98. *
  99. * The document start and end indicators are represented by:
  100. *
  101. * DOCUMENT-START
  102. * DOCUMENT-END
  103. *
  104. * Note that if a YAML stream contains an implicit document (without '---'
  105. * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
  106. * produced.
  107. *
  108. * In the following examples, we present whole documents together with the
  109. * produced tokens.
  110. *
  111. * 1. An implicit document:
  112. *
  113. * 'a scalar'
  114. *
  115. * Tokens:
  116. *
  117. * STREAM-START(utf-8)
  118. * SCALAR("a scalar",single-quoted)
  119. * STREAM-END
  120. *
  121. * 2. An explicit document:
  122. *
  123. * ---
  124. * 'a scalar'
  125. * ...
  126. *
  127. * Tokens:
  128. *
  129. * STREAM-START(utf-8)
  130. * DOCUMENT-START
  131. * SCALAR("a scalar",single-quoted)
  132. * DOCUMENT-END
  133. * STREAM-END
  134. *
  135. * 3. Several documents in a stream:
  136. *
  137. * 'a scalar'
  138. * ---
  139. * 'another scalar'
  140. * ---
  141. * 'yet another scalar'
  142. *
  143. * Tokens:
  144. *
  145. * STREAM-START(utf-8)
  146. * SCALAR("a scalar",single-quoted)
  147. * DOCUMENT-START
  148. * SCALAR("another scalar",single-quoted)
  149. * DOCUMENT-START
  150. * SCALAR("yet another scalar",single-quoted)
  151. * STREAM-END
  152. *
  153. * We have already introduced the SCALAR token above. The following tokens are
  154. * used to describe aliases, anchors, tag, and scalars:
  155. *
  156. * ALIAS(anchor)
  157. * ANCHOR(anchor)
  158. * TAG(handle,suffix)
  159. * SCALAR(value,style)
  160. *
  161. * The following series of examples illustrate the usage of these tokens:
  162. *
  163. * 1. A recursive sequence:
  164. *
  165. * &A [ *A ]
  166. *
  167. * Tokens:
  168. *
  169. * STREAM-START(utf-8)
  170. * ANCHOR("A")
  171. * FLOW-SEQUENCE-START
  172. * ALIAS("A")
  173. * FLOW-SEQUENCE-END
  174. * STREAM-END
  175. *
  176. * 2. A tagged scalar:
  177. *
  178. * !!float "3.14" # A good approximation.
  179. *
  180. * Tokens:
  181. *
  182. * STREAM-START(utf-8)
  183. * TAG("!!","float")
  184. * SCALAR("3.14",double-quoted)
  185. * STREAM-END
  186. *
  187. * 3. Various scalar styles:
  188. *
  189. * --- # Implicit empty plain scalars do not produce tokens.
  190. * --- a plain scalar
  191. * --- 'a single-quoted scalar'
  192. * --- "a double-quoted scalar"
  193. * --- |-
  194. * a literal scalar
  195. * --- >-
  196. * a folded
  197. * scalar
  198. *
  199. * Tokens:
  200. *
  201. * STREAM-START(utf-8)
  202. * DOCUMENT-START
  203. * DOCUMENT-START
  204. * SCALAR("a plain scalar",plain)
  205. * DOCUMENT-START
  206. * SCALAR("a single-quoted scalar",single-quoted)
  207. * DOCUMENT-START
  208. * SCALAR("a double-quoted scalar",double-quoted)
  209. * DOCUMENT-START
  210. * SCALAR("a literal scalar",literal)
  211. * DOCUMENT-START
  212. * SCALAR("a folded scalar",folded)
  213. * STREAM-END
  214. *
  215. * Now it's time to review collection-related tokens. We will start with
  216. * flow collections:
  217. *
  218. * FLOW-SEQUENCE-START
  219. * FLOW-SEQUENCE-END
  220. * FLOW-MAPPING-START
  221. * FLOW-MAPPING-END
  222. * FLOW-ENTRY
  223. * KEY
  224. * VALUE
  225. *
  226. * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
  227. * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
  228. * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
  229. * indicators '?' and ':', which are used for denoting mapping keys and values,
  230. * are represented by the KEY and VALUE tokens.
  231. *
  232. * The following examples show flow collections:
  233. *
  234. * 1. A flow sequence:
  235. *
  236. * [item 1, item 2, item 3]
  237. *
  238. * Tokens:
  239. *
  240. * STREAM-START(utf-8)
  241. * FLOW-SEQUENCE-START
  242. * SCALAR("item 1",plain)
  243. * FLOW-ENTRY
  244. * SCALAR("item 2",plain)
  245. * FLOW-ENTRY
  246. * SCALAR("item 3",plain)
  247. * FLOW-SEQUENCE-END
  248. * STREAM-END
  249. *
  250. * 2. A flow mapping:
  251. *
  252. * {
  253. * a simple key: a value, # Note that the KEY token is produced.
  254. * ? a complex key: another value,
  255. * }
  256. *
  257. * Tokens:
  258. *
  259. * STREAM-START(utf-8)
  260. * FLOW-MAPPING-START
  261. * KEY
  262. * SCALAR("a simple key",plain)
  263. * VALUE
  264. * SCALAR("a value",plain)
  265. * FLOW-ENTRY
  266. * KEY
  267. * SCALAR("a complex key",plain)
  268. * VALUE
  269. * SCALAR("another value",plain)
  270. * FLOW-ENTRY
  271. * FLOW-MAPPING-END
  272. * STREAM-END
  273. *
  274. * A simple key is a key which is not denoted by the '?' indicator. Note that
  275. * the Scanner still produce the KEY token whenever it encounters a simple key.
  276. *
  277. * For scanning block collections, the following tokens are used (note that we
  278. * repeat KEY and VALUE here):
  279. *
  280. * BLOCK-SEQUENCE-START
  281. * BLOCK-MAPPING-START
  282. * BLOCK-END
  283. * BLOCK-ENTRY
  284. * KEY
  285. * VALUE
  286. *
  287. * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
  288. * increase that precedes a block collection (cf. the INDENT token in Python).
  289. * The token BLOCK-END denote indentation decrease that ends a block collection
  290. * (cf. the DEDENT token in Python). However YAML has some syntax pecularities
  291. * that makes detections of these tokens more complex.
  292. *
  293. * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
  294. * '-', '?', and ':' correspondingly.
  295. *
  296. * The following examples show how the tokens BLOCK-SEQUENCE-START,
  297. * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
  298. *
  299. * 1. Block sequences:
  300. *
  301. * - item 1
  302. * - item 2
  303. * -
  304. * - item 3.1
  305. * - item 3.2
  306. * -
  307. * key 1: value 1
  308. * key 2: value 2
  309. *
  310. * Tokens:
  311. *
  312. * STREAM-START(utf-8)
  313. * BLOCK-SEQUENCE-START
  314. * BLOCK-ENTRY
  315. * SCALAR("item 1",plain)
  316. * BLOCK-ENTRY
  317. * SCALAR("item 2",plain)
  318. * BLOCK-ENTRY
  319. * BLOCK-SEQUENCE-START
  320. * BLOCK-ENTRY
  321. * SCALAR("item 3.1",plain)
  322. * BLOCK-ENTRY
  323. * SCALAR("item 3.2",plain)
  324. * BLOCK-END
  325. * BLOCK-ENTRY
  326. * BLOCK-MAPPING-START
  327. * KEY
  328. * SCALAR("key 1",plain)
  329. * VALUE
  330. * SCALAR("value 1",plain)
  331. * KEY
  332. * SCALAR("key 2",plain)
  333. * VALUE
  334. * SCALAR("value 2",plain)
  335. * BLOCK-END
  336. * BLOCK-END
  337. * STREAM-END
  338. *
  339. * 2. Block mappings:
  340. *
  341. * a simple key: a value # The KEY token is produced here.
  342. * ? a complex key
  343. * : another value
  344. * a mapping:
  345. * key 1: value 1
  346. * key 2: value 2
  347. * a sequence:
  348. * - item 1
  349. * - item 2
  350. *
  351. * Tokens:
  352. *
  353. * STREAM-START(utf-8)
  354. * BLOCK-MAPPING-START
  355. * KEY
  356. * SCALAR("a simple key",plain)
  357. * VALUE
  358. * SCALAR("a value",plain)
  359. * KEY
  360. * SCALAR("a complex key",plain)
  361. * VALUE
  362. * SCALAR("another value",plain)
  363. * KEY
  364. * SCALAR("a mapping",plain)
  365. * BLOCK-MAPPING-START
  366. * KEY
  367. * SCALAR("key 1",plain)
  368. * VALUE
  369. * SCALAR("value 1",plain)
  370. * KEY
  371. * SCALAR("key 2",plain)
  372. * VALUE
  373. * SCALAR("value 2",plain)
  374. * BLOCK-END
  375. * KEY
  376. * SCALAR("a sequence",plain)
  377. * VALUE
  378. * BLOCK-SEQUENCE-START
  379. * BLOCK-ENTRY
  380. * SCALAR("item 1",plain)
  381. * BLOCK-ENTRY
  382. * SCALAR("item 2",plain)
  383. * BLOCK-END
  384. * BLOCK-END
  385. * STREAM-END
  386. *
  387. * YAML does not always require to start a new block collection from a new
  388. * line. If the current line contains only '-', '?', and ':' indicators, a new
  389. * block collection may start at the current line. The following examples
  390. * illustrate this case:
  391. *
  392. * 1. Collections in a sequence:
  393. *
  394. * - - item 1
  395. * - item 2
  396. * - key 1: value 1
  397. * key 2: value 2
  398. * - ? complex key
  399. * : complex value
  400. *
  401. * Tokens:
  402. *
  403. * STREAM-START(utf-8)
  404. * BLOCK-SEQUENCE-START
  405. * BLOCK-ENTRY
  406. * BLOCK-SEQUENCE-START
  407. * BLOCK-ENTRY
  408. * SCALAR("item 1",plain)
  409. * BLOCK-ENTRY
  410. * SCALAR("item 2",plain)
  411. * BLOCK-END
  412. * BLOCK-ENTRY
  413. * BLOCK-MAPPING-START
  414. * KEY
  415. * SCALAR("key 1",plain)
  416. * VALUE
  417. * SCALAR("value 1",plain)
  418. * KEY
  419. * SCALAR("key 2",plain)
  420. * VALUE
  421. * SCALAR("value 2",plain)
  422. * BLOCK-END
  423. * BLOCK-ENTRY
  424. * BLOCK-MAPPING-START
  425. * KEY
  426. * SCALAR("complex key")
  427. * VALUE
  428. * SCALAR("complex value")
  429. * BLOCK-END
  430. * BLOCK-END
  431. * STREAM-END
  432. *
  433. * 2. Collections in a mapping:
  434. *
  435. * ? a sequence
  436. * : - item 1
  437. * - item 2
  438. * ? a mapping
  439. * : key 1: value 1
  440. * key 2: value 2
  441. *
  442. * Tokens:
  443. *
  444. * STREAM-START(utf-8)
  445. * BLOCK-MAPPING-START
  446. * KEY
  447. * SCALAR("a sequence",plain)
  448. * VALUE
  449. * BLOCK-SEQUENCE-START
  450. * BLOCK-ENTRY
  451. * SCALAR("item 1",plain)
  452. * BLOCK-ENTRY
  453. * SCALAR("item 2",plain)
  454. * BLOCK-END
  455. * KEY
  456. * SCALAR("a mapping",plain)
  457. * VALUE
  458. * BLOCK-MAPPING-START
  459. * KEY
  460. * SCALAR("key 1",plain)
  461. * VALUE
  462. * SCALAR("value 1",plain)
  463. * KEY
  464. * SCALAR("key 2",plain)
  465. * VALUE
  466. * SCALAR("value 2",plain)
  467. * BLOCK-END
  468. * BLOCK-END
  469. * STREAM-END
  470. *
  471. * YAML also permits non-indented sequences if they are included into a block
  472. * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
  473. *
  474. * key:
  475. * - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
  476. * - item 2
  477. *
  478. * Tokens:
  479. *
  480. * STREAM-START(utf-8)
  481. * BLOCK-MAPPING-START
  482. * KEY
  483. * SCALAR("key",plain)
  484. * VALUE
  485. * BLOCK-ENTRY
  486. * SCALAR("item 1",plain)
  487. * BLOCK-ENTRY
  488. * SCALAR("item 2",plain)
  489. * BLOCK-END
  490. */
  491. /*
  492. * Ensure that the buffer contains the required number of characters.
  493. * Return 1 on success, 0 on failure (reader error or memory error).
  494. */
  495. func cache(parser *yaml_parser_t, length int) bool {
  496. if parser.unread >= length {
  497. return true
  498. }
  499. return yaml_parser_update_buffer(parser, length)
  500. }
  501. /*
  502. * Advance the buffer pointer.
  503. */
  504. func skip(parser *yaml_parser_t) {
  505. parser.mark.index++
  506. parser.mark.column++
  507. parser.unread--
  508. parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
  509. }
  510. func skip_line(parser *yaml_parser_t) {
  511. if is_crlf_at(parser.buffer, parser.buffer_pos) {
  512. parser.mark.index += 2
  513. parser.mark.column = 0
  514. parser.mark.line++
  515. parser.unread -= 2
  516. parser.buffer_pos += 2
  517. } else if is_break_at(parser.buffer, parser.buffer_pos) {
  518. parser.mark.index++
  519. parser.mark.column = 0
  520. parser.mark.line++
  521. parser.unread--
  522. parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
  523. }
  524. }
  525. /*
  526. * Copy a character to a string buffer and advance pointers.
  527. */
  528. func read(parser *yaml_parser_t, s []byte) []byte {
  529. w := width(parser.buffer[parser.buffer_pos])
  530. if w == 0 {
  531. panic("invalid character sequence")
  532. }
  533. if len(s) == 0 {
  534. s = make([]byte, 0, 32)
  535. }
  536. if w == 1 && len(s)+w <= cap(s) {
  537. s = s[:len(s)+1]
  538. s[len(s)-1] = parser.buffer[parser.buffer_pos]
  539. parser.buffer_pos++
  540. } else {
  541. s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
  542. parser.buffer_pos += w
  543. }
  544. parser.mark.index++
  545. parser.mark.column++
  546. parser.unread--
  547. return s
  548. }
  549. /*
  550. * Copy a line break character to a string buffer and advance pointers.
  551. */
  552. func read_line(parser *yaml_parser_t, s []byte) []byte {
  553. buf := parser.buffer
  554. pos := parser.buffer_pos
  555. if buf[pos] == '\r' && buf[pos+1] == '\n' {
  556. /* CR LF . LF */
  557. s = append(s, '\n')
  558. parser.buffer_pos += 2
  559. parser.mark.index++
  560. parser.unread--
  561. } else if buf[pos] == '\r' || buf[pos] == '\n' {
  562. /* CR|LF . LF */
  563. s = append(s, '\n')
  564. parser.buffer_pos += 1
  565. } else if buf[pos] == '\xC2' && buf[pos+1] == '\x85' {
  566. /* NEL . LF */
  567. s = append(s, '\n')
  568. parser.buffer_pos += 2
  569. } else if buf[pos] == '\xE2' && buf[pos+1] == '\x80' &&
  570. (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9') {
  571. // LS|PS . LS|PS
  572. s = append(s, buf[parser.buffer_pos:pos+3]...)
  573. parser.buffer_pos += 3
  574. } else {
  575. return s
  576. }
  577. parser.mark.index++
  578. parser.mark.column = 0
  579. parser.mark.line++
  580. parser.unread--
  581. return s
  582. }
  583. /*
  584. * Get the next token.
  585. */
  586. func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
  587. /* Erase the token object. */
  588. *token = yaml_token_t{}
  589. /* No tokens after STREAM-END or error. */
  590. if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
  591. return true
  592. }
  593. /* Ensure that the tokens queue contains enough tokens. */
  594. if !parser.token_available {
  595. if !yaml_parser_fetch_more_tokens(parser) {
  596. return false
  597. }
  598. }
  599. /* Fetch the next token from the queue. */
  600. *token = parser.tokens[parser.tokens_head]
  601. parser.tokens_head++
  602. parser.token_available = false
  603. parser.tokens_parsed++
  604. if token.token_type == yaml_STREAM_END_TOKEN {
  605. parser.stream_end_produced = true
  606. }
  607. return true
  608. }
  609. /*
  610. * Set the scanner error and return 0.
  611. */
  612. func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string,
  613. context_mark YAML_mark_t, problem string) bool {
  614. parser.error = yaml_SCANNER_ERROR
  615. parser.context = context
  616. parser.context_mark = context_mark
  617. parser.problem = problem
  618. parser.problem_mark = parser.mark
  619. return false
  620. }
  621. func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark YAML_mark_t, problem string) bool {
  622. context := "while parsing a %TAG directive"
  623. if directive {
  624. context = "while parsing a tag"
  625. }
  626. return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
  627. }
  628. /*
  629. * Ensure that the tokens queue contains at least one token which can be
  630. * returned to the Parser.
  631. */
  632. func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
  633. /* While we need more tokens to fetch, do it. */
  634. for {
  635. /*
  636. * Check if we really need to fetch more tokens.
  637. */
  638. need_more_tokens := false
  639. if parser.tokens_head == len(parser.tokens) {
  640. /* Queue is empty. */
  641. need_more_tokens = true
  642. } else {
  643. /* Check if any potential simple key may occupy the head position. */
  644. if !yaml_parser_stale_simple_keys(parser) {
  645. return false
  646. }
  647. for i := range parser.simple_keys {
  648. simple_key := &parser.simple_keys[i]
  649. if simple_key.possible &&
  650. simple_key.token_number == parser.tokens_parsed {
  651. need_more_tokens = true
  652. break
  653. }
  654. }
  655. }
  656. if len(parser.simple_keys) > 0 {
  657. }
  658. /* We are finished. */
  659. if !need_more_tokens {
  660. break
  661. }
  662. /* Fetch the next token. */
  663. if !yaml_parser_fetch_next_token(parser) {
  664. return false
  665. }
  666. }
  667. parser.token_available = true
  668. return true
  669. }
  670. /*
  671. * The dispatcher for token fetchers.
  672. */
  673. func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
  674. /* Ensure that the buffer is initialized. */
  675. if !cache(parser, 1) {
  676. return false
  677. }
  678. /* Check if we just started scanning. Fetch STREAM-START then. */
  679. if !parser.stream_start_produced {
  680. return yaml_parser_fetch_stream_start(parser)
  681. }
  682. /* Eat whitespaces and comments until we reach the next token. */
  683. if !yaml_parser_scan_to_next_token(parser) {
  684. return false
  685. }
  686. /* Remove obsolete potential simple keys. */
  687. if !yaml_parser_stale_simple_keys(parser) {
  688. return false
  689. }
  690. /* Check the indentation level against the current column. */
  691. if !yaml_parser_unroll_indent(parser, parser.mark.column) {
  692. return false
  693. }
  694. /*
  695. * Ensure that the buffer contains at least 4 characters. 4 is the length
  696. * of the longest indicators ('--- ' and '... ').
  697. */
  698. if !cache(parser, 4) {
  699. return false
  700. }
  701. /* Is it the end of the stream? */
  702. buf := parser.buffer
  703. pos := parser.buffer_pos
  704. if is_z(buf[pos]) {
  705. return yaml_parser_fetch_stream_end(parser)
  706. }
  707. /* Is it a directive? */
  708. if parser.mark.column == 0 && buf[pos] == '%' {
  709. return yaml_parser_fetch_directive(parser)
  710. }
  711. /* Is it the document start indicator? */
  712. if parser.mark.column == 0 &&
  713. buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' &&
  714. is_blankz_at(buf, pos+3) {
  715. return yaml_parser_fetch_document_indicator(parser,
  716. yaml_DOCUMENT_START_TOKEN)
  717. }
  718. /* Is it the document end indicator? */
  719. if parser.mark.column == 0 &&
  720. buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' &&
  721. is_blankz_at(buf, pos+3) {
  722. return yaml_parser_fetch_document_indicator(parser,
  723. yaml_DOCUMENT_END_TOKEN)
  724. }
  725. /* Is it the flow sequence start indicator? */
  726. if buf[pos] == '[' {
  727. return yaml_parser_fetch_flow_collection_start(parser,
  728. yaml_FLOW_SEQUENCE_START_TOKEN)
  729. }
  730. /* Is it the flow mapping start indicator? */
  731. if buf[pos] == '{' {
  732. return yaml_parser_fetch_flow_collection_start(parser,
  733. yaml_FLOW_MAPPING_START_TOKEN)
  734. }
  735. /* Is it the flow sequence end indicator? */
  736. if buf[pos] == ']' {
  737. return yaml_parser_fetch_flow_collection_end(parser,
  738. yaml_FLOW_SEQUENCE_END_TOKEN)
  739. }
  740. /* Is it the flow mapping end indicator? */
  741. if buf[pos] == '}' {
  742. return yaml_parser_fetch_flow_collection_end(parser,
  743. yaml_FLOW_MAPPING_END_TOKEN)
  744. }
  745. /* Is it the flow entry indicator? */
  746. if buf[pos] == ',' {
  747. return yaml_parser_fetch_flow_entry(parser)
  748. }
  749. /* Is it the block entry indicator? */
  750. if buf[pos] == '-' && is_blankz_at(buf, pos+1) {
  751. return yaml_parser_fetch_block_entry(parser)
  752. }
  753. /* Is it the key indicator? */
  754. if buf[pos] == '?' &&
  755. (parser.flow_level > 0 || is_blankz_at(buf, pos+1)) {
  756. return yaml_parser_fetch_key(parser)
  757. }
  758. /* Is it the value indicator? */
  759. if buf[pos] == ':' &&
  760. (parser.flow_level > 0 || is_blankz_at(buf, pos+1)) {
  761. return yaml_parser_fetch_value(parser)
  762. }
  763. /* Is it an alias? */
  764. if buf[pos] == '*' {
  765. return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
  766. }
  767. /* Is it an anchor? */
  768. if buf[pos] == '&' {
  769. return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
  770. }
  771. /* Is it a tag? */
  772. if buf[pos] == '!' {
  773. return yaml_parser_fetch_tag(parser)
  774. }
  775. /* Is it a literal scalar? */
  776. if buf[pos] == '|' && parser.flow_level == 0 {
  777. return yaml_parser_fetch_block_scalar(parser, true)
  778. }
  779. /* Is it a folded scalar? */
  780. if buf[pos] == '>' && parser.flow_level == 0 {
  781. return yaml_parser_fetch_block_scalar(parser, false)
  782. }
  783. /* Is it a single-quoted scalar? */
  784. if buf[pos] == '\'' {
  785. return yaml_parser_fetch_flow_scalar(parser, true)
  786. }
  787. /* Is it a double-quoted scalar? */
  788. if buf[pos] == '"' {
  789. return yaml_parser_fetch_flow_scalar(parser, false)
  790. }
  791. /*
  792. * Is it a plain scalar?
  793. *
  794. * A plain scalar may start with any non-blank characters except
  795. *
  796. * '-', '?', ':', ',', '[', ']', '{', '}',
  797. * '#', '&', '*', '!', '|', '>', '\'', '\"',
  798. * '%', '@', '`'.
  799. *
  800. * In the block context (and, for the '-' indicator, in the flow context
  801. * too), it may also start with the characters
  802. *
  803. * '-', '?', ':'
  804. *
  805. * if it is followed by a non-space character.
  806. *
  807. * The last rule is more restrictive than the specification requires.
  808. */
  809. b := buf[pos]
  810. if !(is_blankz_at(buf, pos) || b == '-' ||
  811. b == '?' || b == ':' ||
  812. b == ',' || b == '[' ||
  813. b == ']' || b == '{' ||
  814. b == '}' || b == '#' ||
  815. b == '&' || b == '*' ||
  816. b == '!' || b == '|' ||
  817. b == '>' || b == '\'' ||
  818. b == '"' || b == '%' ||
  819. b == '@' || b == '`') ||
  820. (b == '-' && !is_blank(buf[pos+1])) ||
  821. (parser.flow_level == 0 &&
  822. (buf[pos] == '?' || buf[pos] == ':') &&
  823. !is_blank(buf[pos+1])) {
  824. return yaml_parser_fetch_plain_scalar(parser)
  825. }
  826. /*
  827. * If we don't determine the token type so far, it is an error.
  828. */
  829. return yaml_parser_set_scanner_error(parser,
  830. "while scanning for the next token", parser.mark,
  831. "found character that cannot start any token")
  832. }
  833. /*
  834. * Check the list of potential simple keys and remove the positions that
  835. * cannot contain simple keys anymore.
  836. */
  837. func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
  838. /* Check for a potential simple key for each flow level. */
  839. for i := range parser.simple_keys {
  840. /*
  841. * The specification requires that a simple key
  842. *
  843. * - is limited to a single line,
  844. * - is shorter than 1024 characters.
  845. */
  846. simple_key := &parser.simple_keys[i]
  847. if simple_key.possible &&
  848. (simple_key.mark.line < parser.mark.line ||
  849. simple_key.mark.index+1024 < parser.mark.index) {
  850. /* Check if the potential simple key to be removed is required. */
  851. if simple_key.required {
  852. return yaml_parser_set_scanner_error(parser,
  853. "while scanning a simple key", simple_key.mark,
  854. "could not find expected ':'")
  855. }
  856. simple_key.possible = false
  857. }
  858. }
  859. return true
  860. }
  861. /*
  862. * Check if a simple key may start at the current position and add it if
  863. * needed.
  864. */
  865. func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
  866. /*
  867. * A simple key is required at the current position if the scanner is in
  868. * the block context and the current column coincides with the indentation
  869. * level.
  870. */
  871. required := (parser.flow_level == 0 &&
  872. parser.indent == parser.mark.column)
  873. /*
  874. * A simple key is required only when it is the first token in the current
  875. * line. Therefore it is always allowed. But we add a check anyway.
  876. */
  877. if required && !parser.simple_key_allowed {
  878. panic("impossible") /* Impossible. */
  879. }
  880. /*
  881. * If the current position may start a simple key, save it.
  882. */
  883. if parser.simple_key_allowed {
  884. simple_key := yaml_simple_key_t{
  885. possible: true,
  886. required: required,
  887. token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
  888. }
  889. simple_key.mark = parser.mark
  890. if !yaml_parser_remove_simple_key(parser) {
  891. return false
  892. }
  893. parser.simple_keys[len(parser.simple_keys)-1] = simple_key
  894. }
  895. return true
  896. }
  897. /*
  898. * Remove a potential simple key at the current flow level.
  899. */
  900. func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
  901. simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
  902. if simple_key.possible {
  903. /* If the key is required, it is an error. */
  904. if simple_key.required {
  905. return yaml_parser_set_scanner_error(parser,
  906. "while scanning a simple key", simple_key.mark,
  907. "could not find expected ':'")
  908. }
  909. }
  910. /* Remove the key from the stack. */
  911. simple_key.possible = false
  912. return true
  913. }
  914. /*
  915. * Increase the flow level and resize the simple key list if needed.
  916. */
  917. func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
  918. /* Reset the simple key on the next level. */
  919. parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
  920. /* Increase the flow level. */
  921. parser.flow_level++
  922. return true
  923. }
  924. /*
  925. * Decrease the flow level.
  926. */
  927. func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
  928. if parser.flow_level > 0 {
  929. parser.flow_level--
  930. parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
  931. }
  932. return true
  933. }
  934. /*
  935. * Push the current indentation level to the stack and set the new level
  936. * the current column is greater than the indentation level. In this case,
  937. * append or insert the specified token into the token queue.
  938. *
  939. */
  940. func yaml_parser_roll_indent(parser *yaml_parser_t, column int,
  941. number int, token_type yaml_token_type_t, mark YAML_mark_t) bool {
  942. /* In the flow context, do nothing. */
  943. if parser.flow_level > 0 {
  944. return true
  945. }
  946. if parser.indent == -1 || parser.indent < column {
  947. /*
  948. * Push the current indentation level to the stack and set the new
  949. * indentation level.
  950. */
  951. parser.indents = append(parser.indents, parser.indent)
  952. parser.indent = column
  953. /* Create a token and insert it into the queue. */
  954. token := yaml_token_t{
  955. token_type: token_type,
  956. start_mark: mark,
  957. end_mark: mark,
  958. }
  959. // number == -1 -> enqueue otherwise insert
  960. if number > -1 {
  961. number -= parser.tokens_parsed
  962. }
  963. insert_token(parser, number, &token)
  964. }
  965. return true
  966. }
  967. /*
  968. * Pop indentation levels from the indents stack until the current level
  969. * becomes less or equal to the column. For each indentation level, append
  970. * the BLOCK-END token.
  971. */
  972. func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
  973. /* In the flow context, do nothing. */
  974. if parser.flow_level > 0 {
  975. return true
  976. }
  977. /*
  978. * column is unsigned and parser->indent is signed, so if
  979. * parser->indent is less than zero the conditional in the while
  980. * loop below is incorrect. Guard against that.
  981. */
  982. if parser.indent < 0 {
  983. return true
  984. }
  985. /* Loop through the indentation levels in the stack. */
  986. for parser.indent > column {
  987. /* Create a token and append it to the queue. */
  988. token := yaml_token_t{
  989. token_type: yaml_BLOCK_END_TOKEN,
  990. start_mark: parser.mark,
  991. end_mark: parser.mark,
  992. }
  993. insert_token(parser, -1, &token)
  994. /* Pop the indentation level. */
  995. parser.indent = parser.indents[len(parser.indents)-1]
  996. parser.indents = parser.indents[:len(parser.indents)-1]
  997. }
  998. return true
  999. }
  1000. /*
  1001. * Pop indentation levels from the indents stack until the current
  1002. * level resets to -1. For each indentation level, append the
  1003. * BLOCK-END token.
  1004. */
  1005. func yaml_parser_reset_indent(parser *yaml_parser_t) bool {
  1006. /* In the flow context, do nothing. */
  1007. if parser.flow_level > 0 {
  1008. return true
  1009. }
  1010. /* Loop through the indentation levels in the stack. */
  1011. for parser.indent > -1 {
  1012. /* Create a token and append it to the queue. */
  1013. token := yaml_token_t{
  1014. token_type: yaml_BLOCK_END_TOKEN,
  1015. start_mark: parser.mark,
  1016. end_mark: parser.mark,
  1017. }
  1018. insert_token(parser, -1, &token)
  1019. /* Pop the indentation level. */
  1020. parser.indent = parser.indents[len(parser.indents)-1]
  1021. parser.indents = parser.indents[:len(parser.indents)-1]
  1022. }
  1023. return true
  1024. }
  1025. /*
  1026. * Initialize the scanner and produce the STREAM-START token.
  1027. */
  1028. func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
  1029. /* Set the initial indentation. */
  1030. parser.indent = -1
  1031. /* Initialize the simple key stack. */
  1032. parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
  1033. /* A simple key is allowed at the beginning of the stream. */
  1034. parser.simple_key_allowed = true
  1035. /* We have started. */
  1036. parser.stream_start_produced = true
  1037. /* Create the STREAM-START token and append it to the queue. */
  1038. token := yaml_token_t{
  1039. token_type: yaml_STREAM_START_TOKEN,
  1040. start_mark: parser.mark,
  1041. end_mark: parser.mark,
  1042. encoding: parser.encoding,
  1043. }
  1044. insert_token(parser, -1, &token)
  1045. return true
  1046. }
  1047. /*
  1048. * Produce the STREAM-END token and shut down the scanner.
  1049. */
  1050. func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
  1051. /* Force new line. */
  1052. if parser.mark.column != 0 {
  1053. parser.mark.column = 0
  1054. parser.mark.line++
  1055. }
  1056. /* Reset the indentation level. */
  1057. if !yaml_parser_reset_indent(parser) {
  1058. return false
  1059. }
  1060. /* Reset simple keys. */
  1061. if !yaml_parser_remove_simple_key(parser) {
  1062. return false
  1063. }
  1064. parser.simple_key_allowed = false
  1065. /* Create the STREAM-END token and append it to the queue. */
  1066. token := yaml_token_t{
  1067. token_type: yaml_STREAM_END_TOKEN,
  1068. start_mark: parser.mark,
  1069. end_mark: parser.mark,
  1070. }
  1071. insert_token(parser, -1, &token)
  1072. return true
  1073. }
  1074. /*
  1075. * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
  1076. */
  1077. func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
  1078. /* Reset the indentation level. */
  1079. if !yaml_parser_reset_indent(parser) {
  1080. return false
  1081. }
  1082. /* Reset simple keys. */
  1083. if !yaml_parser_remove_simple_key(parser) {
  1084. return false
  1085. }
  1086. parser.simple_key_allowed = false
  1087. /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
  1088. var token yaml_token_t
  1089. if !yaml_parser_scan_directive(parser, &token) {
  1090. return false
  1091. }
  1092. /* Append the token to the queue. */
  1093. insert_token(parser, -1, &token)
  1094. return true
  1095. }
  1096. /*
  1097. * Produce the DOCUMENT-START or DOCUMENT-END token.
  1098. */
  1099. func yaml_parser_fetch_document_indicator(parser *yaml_parser_t,
  1100. token_type yaml_token_type_t) bool {
  1101. /* Reset the indentation level. */
  1102. if !yaml_parser_reset_indent(parser) {
  1103. return false
  1104. }
  1105. /* Reset simple keys. */
  1106. if !yaml_parser_remove_simple_key(parser) {
  1107. return false
  1108. }
  1109. parser.simple_key_allowed = false
  1110. /* Consume the token. */
  1111. start_mark := parser.mark
  1112. skip(parser)
  1113. skip(parser)
  1114. skip(parser)
  1115. end_mark := parser.mark
  1116. /* Create the DOCUMENT-START or DOCUMENT-END token. */
  1117. token := yaml_token_t{
  1118. token_type: token_type,
  1119. start_mark: start_mark,
  1120. end_mark: end_mark,
  1121. }
  1122. /* Append the token to the queue. */
  1123. insert_token(parser, -1, &token)
  1124. return true
  1125. }
  1126. /*
  1127. * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
  1128. */
  1129. func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t,
  1130. token_type yaml_token_type_t) bool {
  1131. /* The indicators '[' and '{' may start a simple key. */
  1132. if !yaml_parser_save_simple_key(parser) {
  1133. return false
  1134. }
  1135. /* Increase the flow level. */
  1136. if !yaml_parser_increase_flow_level(parser) {
  1137. return false
  1138. }
  1139. /* A simple key may follow the indicators '[' and '{'. */
  1140. parser.simple_key_allowed = true
  1141. /* Consume the token. */
  1142. start_mark := parser.mark
  1143. skip(parser)
  1144. end_mark := parser.mark
  1145. /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */
  1146. token := yaml_token_t{
  1147. token_type: token_type,
  1148. start_mark: start_mark,
  1149. end_mark: end_mark,
  1150. }
  1151. /* Append the token to the queue. */
  1152. insert_token(parser, -1, &token)
  1153. return true
  1154. }
  1155. /*
  1156. * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
  1157. */
  1158. func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t,
  1159. token_type yaml_token_type_t) bool {
  1160. /* Reset any potential simple key on the current flow level. */
  1161. if !yaml_parser_remove_simple_key(parser) {
  1162. return false
  1163. }
  1164. /* Decrease the flow level. */
  1165. if !yaml_parser_decrease_flow_level(parser) {
  1166. return false
  1167. }
  1168. /* No simple keys after the indicators ']' and '}'. */
  1169. parser.simple_key_allowed = false
  1170. /* Consume the token. */
  1171. start_mark := parser.mark
  1172. skip(parser)
  1173. end_mark := parser.mark
  1174. /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */
  1175. token := yaml_token_t{
  1176. token_type: token_type,
  1177. start_mark: start_mark,
  1178. end_mark: end_mark,
  1179. }
  1180. /* Append the token to the queue. */
  1181. insert_token(parser, -1, &token)
  1182. return true
  1183. }
  1184. /*
  1185. * Produce the FLOW-ENTRY token.
  1186. */
  1187. func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
  1188. /* Reset any potential simple keys on the current flow level. */
  1189. if !yaml_parser_remove_simple_key(parser) {
  1190. return false
  1191. }
  1192. /* Simple keys are allowed after ','. */
  1193. parser.simple_key_allowed = true
  1194. /* Consume the token. */
  1195. start_mark := parser.mark
  1196. skip(parser)
  1197. end_mark := parser.mark
  1198. /* Create the FLOW-ENTRY token and append it to the queue. */
  1199. token := yaml_token_t{
  1200. token_type: yaml_FLOW_ENTRY_TOKEN,
  1201. start_mark: start_mark,
  1202. end_mark: end_mark,
  1203. }
  1204. insert_token(parser, -1, &token)
  1205. return true
  1206. }
  1207. /*
  1208. * Produce the BLOCK-ENTRY token.
  1209. */
  1210. func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
  1211. /* Check if the scanner is in the block context. */
  1212. if parser.flow_level == 0 {
  1213. /* Check if we are allowed to start a new entry. */
  1214. if !parser.simple_key_allowed {
  1215. return yaml_parser_set_scanner_error(parser, "", parser.mark,
  1216. "block sequence entries are not allowed in this context")
  1217. }
  1218. /* Add the BLOCK-SEQUENCE-START token if needed. */
  1219. if !yaml_parser_roll_indent(parser, parser.mark.column, -1,
  1220. yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
  1221. return false
  1222. }
  1223. } else {
  1224. /*
  1225. * It is an error for the '-' indicator to occur in the flow context,
  1226. * but we let the Parser detect and report about it because the Parser
  1227. * is able to point to the context.
  1228. */
  1229. }
  1230. /* Reset any potential simple keys on the current flow level. */
  1231. if !yaml_parser_remove_simple_key(parser) {
  1232. return false
  1233. }
  1234. /* Simple keys are allowed after '-'. */
  1235. parser.simple_key_allowed = true
  1236. /* Consume the token. */
  1237. start_mark := parser.mark
  1238. skip(parser)
  1239. end_mark := parser.mark
  1240. /* Create the BLOCK-ENTRY token and append it to the queue. */
  1241. token := yaml_token_t{
  1242. token_type: yaml_BLOCK_ENTRY_TOKEN,
  1243. start_mark: start_mark,
  1244. end_mark: end_mark,
  1245. }
  1246. insert_token(parser, -1, &token)
  1247. return true
  1248. }
  1249. /*
  1250. * Produce the KEY token.
  1251. */
  1252. func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
  1253. /* In the block context, additional checks are required. */
  1254. if parser.flow_level == 0 {
  1255. /* Check if we are allowed to start a new key (not nessesary simple). */
  1256. if !parser.simple_key_allowed {
  1257. return yaml_parser_set_scanner_error(parser, "", parser.mark,
  1258. "mapping keys are not allowed in this context")
  1259. }
  1260. /* Add the BLOCK-MAPPING-START token if needed. */
  1261. if !yaml_parser_roll_indent(parser, parser.mark.column, -1,
  1262. yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
  1263. return false
  1264. }
  1265. }
  1266. /* Reset any potential simple keys on the current flow level. */
  1267. if !yaml_parser_remove_simple_key(parser) {
  1268. return false
  1269. }
  1270. /* Simple keys are allowed after '?' in the block context. */
  1271. parser.simple_key_allowed = (parser.flow_level == 0)
  1272. /* Consume the token. */
  1273. start_mark := parser.mark
  1274. skip(parser)
  1275. end_mark := parser.mark
  1276. /* Create the KEY token and append it to the queue. */
  1277. token := yaml_token_t{
  1278. token_type: yaml_KEY_TOKEN,
  1279. start_mark: start_mark,
  1280. end_mark: end_mark,
  1281. }
  1282. insert_token(parser, -1, &token)
  1283. return true
  1284. }
  1285. /*
  1286. * Produce the VALUE token.
  1287. */
  1288. func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
  1289. simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
  1290. /* Have we found a simple key? */
  1291. if simple_key.possible {
  1292. /* Create the KEY token and insert it into the queue. */
  1293. token := yaml_token_t{
  1294. token_type: yaml_KEY_TOKEN,
  1295. start_mark: simple_key.mark,
  1296. end_mark: simple_key.mark,
  1297. }
  1298. insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
  1299. /* In the block context, we may need to add the BLOCK-MAPPING-START token. */
  1300. if !yaml_parser_roll_indent(parser, simple_key.mark.column,
  1301. simple_key.token_number,
  1302. yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
  1303. return false
  1304. }
  1305. /* Remove the simple key. */
  1306. simple_key.possible = false
  1307. /* A simple key cannot follow another simple key. */
  1308. parser.simple_key_allowed = false
  1309. } else {
  1310. /* The ':' indicator follows a complex key. */
  1311. /* In the block context, extra checks are required. */
  1312. if parser.flow_level == 0 {
  1313. /* Check if we are allowed to start a complex value. */
  1314. if !parser.simple_key_allowed {
  1315. return yaml_parser_set_scanner_error(parser, "", parser.mark,
  1316. "mapping values are not allowed in this context")
  1317. }
  1318. /* Add the BLOCK-MAPPING-START token if needed. */
  1319. if !yaml_parser_roll_indent(parser, parser.mark.column, -1,
  1320. yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
  1321. return false
  1322. }
  1323. }
  1324. /* Simple keys after ':' are allowed in the block context. */
  1325. parser.simple_key_allowed = (parser.flow_level == 0)
  1326. }
  1327. /* Consume the token. */
  1328. start_mark := parser.mark
  1329. skip(parser)
  1330. end_mark := parser.mark
  1331. /* Create the VALUE token and append it to the queue. */
  1332. token := yaml_token_t{
  1333. token_type: yaml_VALUE_TOKEN,
  1334. start_mark: start_mark,
  1335. end_mark: end_mark,
  1336. }
  1337. insert_token(parser, -1, &token)
  1338. return true
  1339. }
  1340. /*
  1341. * Produce the ALIAS or ANCHOR token.
  1342. */
  1343. func yaml_parser_fetch_anchor(parser *yaml_parser_t, token_type yaml_token_type_t) bool {
  1344. /* An anchor or an alias could be a simple key. */
  1345. if !yaml_parser_save_simple_key(parser) {
  1346. return false
  1347. }
  1348. /* A simple key cannot follow an anchor or an alias. */
  1349. parser.simple_key_allowed = false
  1350. /* Create the ALIAS or ANCHOR token and append it to the queue. */
  1351. var token yaml_token_t
  1352. if !yaml_parser_scan_anchor(parser, &token, token_type) {
  1353. return false
  1354. }
  1355. insert_token(parser, -1, &token)
  1356. return true
  1357. }
  1358. /*
  1359. * Produce the TAG token.
  1360. */
  1361. func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
  1362. /* A tag could be a simple key. */
  1363. if !yaml_parser_save_simple_key(parser) {
  1364. return false
  1365. }
  1366. /* A simple key cannot follow a tag. */
  1367. parser.simple_key_allowed = false
  1368. /* Create the TAG token and append it to the queue. */
  1369. var token yaml_token_t
  1370. if !yaml_parser_scan_tag(parser, &token) {
  1371. return false
  1372. }
  1373. insert_token(parser, -1, &token)
  1374. return true
  1375. }
  1376. /*
  1377. * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
  1378. */
  1379. func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
  1380. /* Remove any potential simple keys. */
  1381. if !yaml_parser_remove_simple_key(parser) {
  1382. return false
  1383. }
  1384. /* A simple key may follow a block scalar. */
  1385. parser.simple_key_allowed = true
  1386. /* Create the SCALAR token and append it to the queue. */
  1387. var token yaml_token_t
  1388. if !yaml_parser_scan_block_scalar(parser, &token, literal) {
  1389. return false
  1390. }
  1391. insert_token(parser, -1, &token)
  1392. return true
  1393. }
  1394. /*
  1395. * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
  1396. */
  1397. func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
  1398. /* A plain scalar could be a simple key. */
  1399. if !yaml_parser_save_simple_key(parser) {
  1400. return false
  1401. }
  1402. /* A simple key cannot follow a flow scalar. */
  1403. parser.simple_key_allowed = false
  1404. /* Create the SCALAR token and append it to the queue. */
  1405. var token yaml_token_t
  1406. if !yaml_parser_scan_flow_scalar(parser, &token, single) {
  1407. return false
  1408. }
  1409. insert_token(parser, -1, &token)
  1410. return true
  1411. }
  1412. /*
  1413. * Produce the SCALAR(...,plain) token.
  1414. */
  1415. func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
  1416. /* A plain scalar could be a simple key. */
  1417. if !yaml_parser_save_simple_key(parser) {
  1418. return false
  1419. }
  1420. /* A simple key cannot follow a flow scalar. */
  1421. parser.simple_key_allowed = false
  1422. /* Create the SCALAR token and append it to the queue. */
  1423. var token yaml_token_t
  1424. if !yaml_parser_scan_plain_scalar(parser, &token) {
  1425. return false
  1426. }
  1427. insert_token(parser, -1, &token)
  1428. return true
  1429. }
  1430. /*
  1431. * Eat whitespaces and comments until the next token is found.
  1432. */
  1433. func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
  1434. /* Until the next token is not found. */
  1435. for {
  1436. /* Allow the BOM mark to start a line. */
  1437. if !cache(parser, 1) {
  1438. return false
  1439. }
  1440. if parser.mark.column == 0 && is_bom_at(parser.buffer, parser.buffer_pos) {
  1441. skip(parser)
  1442. }
  1443. /*
  1444. * Eat whitespaces.
  1445. *
  1446. * Tabs are allowed:
  1447. *
  1448. * - in the flow context;
  1449. * - in the block context, but not at the beginning of the line or
  1450. * after '-', '?', or ':' (complex value).
  1451. */
  1452. if !cache(parser, 1) {
  1453. return false
  1454. }
  1455. for parser.buffer[parser.buffer_pos] == ' ' ||
  1456. ((parser.flow_level > 0 || !parser.simple_key_allowed) &&
  1457. parser.buffer[parser.buffer_pos] == '\t') {
  1458. skip(parser)
  1459. if !cache(parser, 1) {
  1460. return false
  1461. }
  1462. }
  1463. /* Eat a comment until a line break. */
  1464. if parser.buffer[parser.buffer_pos] == '#' {
  1465. for !is_breakz_at(parser.buffer, parser.buffer_pos) {
  1466. skip(parser)
  1467. if !cache(parser, 1) {
  1468. return false
  1469. }
  1470. }
  1471. }
  1472. /* If it is a line break, eat it. */
  1473. if is_break_at(parser.buffer, parser.buffer_pos) {
  1474. if !cache(parser, 2) {
  1475. return false
  1476. }
  1477. skip_line(parser)
  1478. /* In the block context, a new line may start a simple key. */
  1479. if parser.flow_level == 0 {
  1480. parser.simple_key_allowed = true
  1481. }
  1482. } else {
  1483. /* We have found a token. */
  1484. break
  1485. }
  1486. }
  1487. return true
  1488. }
  1489. /*
  1490. * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
  1491. *
  1492. * Scope:
  1493. * %YAML 1.1 # a comment \n
  1494. * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1495. * %TAG !yaml! tag:yaml.org,2002: \n
  1496. * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1497. */
  1498. func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
  1499. /* Eat '%'. */
  1500. start_mark := parser.mark
  1501. skip(parser)
  1502. /* Scan the directive name. */
  1503. var name []byte
  1504. if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
  1505. return false
  1506. }
  1507. /* Is it a YAML directive? */
  1508. var major, minor int
  1509. if bytes.Equal(name, []byte("YAML")) {
  1510. /* Scan the VERSION directive value. */
  1511. if !yaml_parser_scan_version_directive_value(parser, start_mark,
  1512. &major, &minor) {
  1513. return false
  1514. }
  1515. end_mark := parser.mark
  1516. /* Create a VERSION-DIRECTIVE token. */
  1517. *token = yaml_token_t{
  1518. token_type: yaml_VERSION_DIRECTIVE_TOKEN,
  1519. start_mark: start_mark,
  1520. end_mark: end_mark,
  1521. major: major,
  1522. minor: minor,
  1523. }
  1524. } else if bytes.Equal(name, []byte("TAG")) {
  1525. /* Is it a TAG directive? */
  1526. /* Scan the TAG directive value. */
  1527. var handle, prefix []byte
  1528. if !yaml_parser_scan_tag_directive_value(parser, start_mark,
  1529. &handle, &prefix) {
  1530. return false
  1531. }
  1532. end_mark := parser.mark
  1533. /* Create a TAG-DIRECTIVE token. */
  1534. *token = yaml_token_t{
  1535. token_type: yaml_TAG_DIRECTIVE_TOKEN,
  1536. start_mark: start_mark,
  1537. end_mark: end_mark,
  1538. value: handle,
  1539. prefix: prefix,
  1540. }
  1541. } else {
  1542. /* Unknown directive. */
  1543. yaml_parser_set_scanner_error(parser, "while scanning a directive",
  1544. start_mark, "found uknown directive name")
  1545. return false
  1546. }
  1547. /* Eat the rest of the line including any comments. */
  1548. if !cache(parser, 1) {
  1549. return false
  1550. }
  1551. for is_blank(parser.buffer[parser.buffer_pos]) {
  1552. skip(parser)
  1553. if !cache(parser, 1) {
  1554. return false
  1555. }
  1556. }
  1557. if parser.buffer[parser.buffer_pos] == '#' {
  1558. for !is_breakz_at(parser.buffer, parser.buffer_pos) {
  1559. skip(parser)
  1560. if !cache(parser, 1) {
  1561. return false
  1562. }
  1563. }
  1564. }
  1565. /* Check if we are at the end of the line. */
  1566. if !is_breakz_at(parser.buffer, parser.buffer_pos) {
  1567. yaml_parser_set_scanner_error(parser, "while scanning a directive",
  1568. start_mark, "did not find expected comment or line break")
  1569. return false
  1570. }
  1571. /* Eat a line break. */
  1572. if is_break_at(parser.buffer, parser.buffer_pos) {
  1573. if !cache(parser, 2) {
  1574. return false
  1575. }
  1576. skip_line(parser)
  1577. }
  1578. return true
  1579. }
  1580. /*
  1581. * Scan the directive name.
  1582. *
  1583. * Scope:
  1584. * %YAML 1.1 # a comment \n
  1585. * ^^^^
  1586. * %TAG !yaml! tag:yaml.org,2002: \n
  1587. * ^^^
  1588. */
  1589. func yaml_parser_scan_directive_name(parser *yaml_parser_t,
  1590. start_mark YAML_mark_t, name *[]byte) bool {
  1591. /* Consume the directive name. */
  1592. if !cache(parser, 1) {
  1593. return false
  1594. }
  1595. var s []byte
  1596. for is_alpha(parser.buffer[parser.buffer_pos]) {
  1597. s = read(parser, s)
  1598. if !cache(parser, 1) {
  1599. return false
  1600. }
  1601. }
  1602. /* Check if the name is empty. */
  1603. if len(s) == 0 {
  1604. yaml_parser_set_scanner_error(parser, "while scanning a directive",
  1605. start_mark, "could not find expected directive name")
  1606. return false
  1607. }
  1608. /* Check for an blank character after the name. */
  1609. if !is_blankz_at(parser.buffer, parser.buffer_pos) {
  1610. yaml_parser_set_scanner_error(parser, "while scanning a directive",
  1611. start_mark, "found unexpected non-alphabetical character")
  1612. return false
  1613. }
  1614. *name = s
  1615. return true
  1616. }
  1617. /*
  1618. * Scan the value of VERSION-DIRECTIVE.
  1619. *
  1620. * Scope:
  1621. * %YAML 1.1 # a comment \n
  1622. * ^^^^^^
  1623. */
  1624. func yaml_parser_scan_version_directive_value(parser *yaml_parser_t,
  1625. start_mark YAML_mark_t, major *int, minor *int) bool {
  1626. /* Eat whitespaces. */
  1627. if !cache(parser, 1) {
  1628. return false
  1629. }
  1630. for is_blank(parser.buffer[parser.buffer_pos]) {
  1631. skip(parser)
  1632. if !cache(parser, 1) {
  1633. return false
  1634. }
  1635. }
  1636. /* Consume the major version number. */
  1637. if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
  1638. return false
  1639. }
  1640. /* Eat '.'. */
  1641. if parser.buffer[parser.buffer_pos] != '.' {
  1642. return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
  1643. start_mark, "did not find expected digit or '.' character")
  1644. }
  1645. skip(parser)
  1646. /* Consume the minor version number. */
  1647. if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
  1648. return false
  1649. }
  1650. return true
  1651. }
  1652. const MAX_NUMBER_LENGTH = 9
  1653. /*
  1654. * Scan the version number of VERSION-DIRECTIVE.
  1655. *
  1656. * Scope:
  1657. * %YAML 1.1 # a comment \n
  1658. * ^
  1659. * %YAML 1.1 # a comment \n
  1660. * ^
  1661. */
  1662. func yaml_parser_scan_version_directive_number(parser *yaml_parser_t,
  1663. start_mark YAML_mark_t, number *int) bool {
  1664. /* Repeat while the next character is digit. */
  1665. if !cache(parser, 1) {
  1666. return false
  1667. }
  1668. value := 0
  1669. length := 0
  1670. for is_digit(parser.buffer[parser.buffer_pos]) {
  1671. /* Check if the number is too long. */
  1672. length++
  1673. if length > MAX_NUMBER_LENGTH {
  1674. return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
  1675. start_mark, "found extremely long version number")
  1676. }
  1677. value = value*10 + as_digit(parser.buffer[parser.buffer_pos])
  1678. skip(parser)
  1679. if !cache(parser, 1) {
  1680. return false
  1681. }
  1682. }
  1683. /* Check if the number was present. */
  1684. if length == 0 {
  1685. return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
  1686. start_mark, "did not find expected version number")
  1687. }
  1688. *number = value
  1689. return true
  1690. }
  1691. /*
  1692. * Scan the value of a TAG-DIRECTIVE token.
  1693. *
  1694. * Scope:
  1695. * %TAG !yaml! tag:yaml.org,2002: \n
  1696. * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1697. */
  1698. func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t,
  1699. start_mark YAML_mark_t, handle, prefix *[]byte) bool {
  1700. /* Eat whitespaces. */
  1701. if !cache(parser, 1) {
  1702. return false
  1703. }
  1704. for is_blank(parser.buffer[parser.buffer_pos]) {
  1705. skip(parser)
  1706. if !cache(parser, 1) {
  1707. return false
  1708. }
  1709. }
  1710. /* Scan a handle. */
  1711. var handle_value []byte
  1712. if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
  1713. return false
  1714. }
  1715. /* Expect a whitespace. */
  1716. if !cache(parser, 1) {
  1717. return false
  1718. }
  1719. if !is_blank(parser.buffer[parser.buffer_pos]) {
  1720. yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
  1721. start_mark, "did not find expected whitespace")
  1722. return false
  1723. }
  1724. /* Eat whitespaces. */
  1725. for is_blank(parser.buffer[parser.buffer_pos]) {
  1726. skip(parser)
  1727. if !cache(parser, 1) {
  1728. return false
  1729. }
  1730. }
  1731. /* Scan a prefix. */
  1732. var prefix_value []byte
  1733. if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
  1734. return false
  1735. }
  1736. /* Expect a whitespace or line break. */
  1737. if !cache(parser, 1) {
  1738. return false
  1739. }
  1740. if !is_blankz_at(parser.buffer, parser.buffer_pos) {
  1741. yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
  1742. start_mark, "did not find expected whitespace or line break")
  1743. return false
  1744. }
  1745. *handle = handle_value
  1746. *prefix = prefix_value
  1747. return true
  1748. }
  1749. func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t,
  1750. token_type yaml_token_type_t) bool {
  1751. /* Eat the indicator character. */
  1752. start_mark := parser.mark
  1753. skip(parser)
  1754. /* Consume the value. */
  1755. if !cache(parser, 1) {
  1756. return false
  1757. }
  1758. var s []byte
  1759. for is_alpha(parser.buffer[parser.buffer_pos]) {
  1760. s = read(parser, s)
  1761. if !cache(parser, 1) {
  1762. return false
  1763. }
  1764. }
  1765. end_mark := parser.mark
  1766. /*
  1767. * Check if length of the anchor is greater than 0 and it is followed by
  1768. * a whitespace character or one of the indicators:
  1769. *
  1770. * '?', ':', ',', ']', '}', '%', '@', '`'.
  1771. */
  1772. b := parser.buffer[parser.buffer_pos]
  1773. if len(s) == 0 || !(is_blankz_at(parser.buffer, parser.buffer_pos) || b == '?' ||
  1774. b == ':' || b == ',' ||
  1775. b == ']' || b == '}' ||
  1776. b == '%' || b == '@' ||
  1777. b == '`') {
  1778. context := "while scanning an anchor"
  1779. if token_type != yaml_ANCHOR_TOKEN {
  1780. context = "while scanning an alias"
  1781. }
  1782. yaml_parser_set_scanner_error(parser, context, start_mark,
  1783. "did not find expected alphabetic or numeric character")
  1784. return false
  1785. }
  1786. /* Create a token. */
  1787. *token = yaml_token_t{
  1788. token_type: token_type,
  1789. start_mark: start_mark,
  1790. end_mark: end_mark,
  1791. value: s,
  1792. }
  1793. return true
  1794. }
  1795. /*
  1796. * Scan a TAG token.
  1797. */
  1798. func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
  1799. start_mark := parser.mark
  1800. /* Check if the tag is in the canonical form. */
  1801. if !cache(parser, 2) {
  1802. return false
  1803. }
  1804. var handle []byte
  1805. var suffix []byte
  1806. if parser.buffer[parser.buffer_pos+1] == '<' {
  1807. /* Set the handle to '' */
  1808. /* Eat '!<' */
  1809. skip(parser)
  1810. skip(parser)
  1811. /* Consume the tag value. */
  1812. if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
  1813. return false
  1814. }
  1815. /* Check for '>' and eat it. */
  1816. if parser.buffer[parser.buffer_pos] != '>' {
  1817. yaml_parser_set_scanner_error(parser, "while scanning a tag",
  1818. start_mark, "did not find the expected '>'")
  1819. return false
  1820. }
  1821. skip(parser)
  1822. } else if is_blank(parser.buffer[parser.buffer_pos+1]) {
  1823. // NON-SPECIFIED
  1824. skip(parser)
  1825. } else {
  1826. /* The tag has either the '!suffix' or the '!handle!suffix' form. */
  1827. /* First, try to scan a handle. */
  1828. if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
  1829. return false
  1830. }
  1831. /* Check if it is, indeed, handle. */
  1832. if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
  1833. /* Scan the suffix now. */
  1834. if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
  1835. return false
  1836. }
  1837. } else {
  1838. /* It wasn't a handle after all. Scan the rest of the tag. */
  1839. if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
  1840. return false
  1841. }
  1842. /* Set the handle to '!'. */
  1843. handle = []byte{'!'}
  1844. /*
  1845. * A special case: the '!' tag. Set the handle to '' and the
  1846. * suffix to '!'.
  1847. */
  1848. if len(suffix) == 0 {
  1849. handle, suffix = suffix, handle
  1850. }
  1851. }
  1852. }
  1853. /* Check the character which ends the tag. */
  1854. if !cache(parser, 1) {
  1855. return false
  1856. }
  1857. if !is_blankz_at(parser.buffer, parser.buffer_pos) {
  1858. yaml_parser_set_scanner_error(parser, "while scanning a tag",
  1859. start_mark, "did not find expected whitespace or line break")
  1860. return false
  1861. }
  1862. end_mark := parser.mark
  1863. /* Create a token. */
  1864. *token = yaml_token_t{
  1865. token_type: yaml_TAG_TOKEN,
  1866. start_mark: start_mark,
  1867. end_mark: end_mark,
  1868. value: handle,
  1869. suffix: suffix,
  1870. }
  1871. return true
  1872. }
  1873. /*
  1874. * Scan a tag handle.
  1875. */
  1876. func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool,
  1877. start_mark YAML_mark_t, handle *[]byte) bool {
  1878. /* Check the initial '!' character. */
  1879. if !cache(parser, 1) {
  1880. return false
  1881. }
  1882. if parser.buffer[parser.buffer_pos] != '!' {
  1883. yaml_parser_set_scanner_tag_error(parser, directive,
  1884. start_mark, "did not find expected '!'")
  1885. return false
  1886. }
  1887. /* Copy the '!' character. */
  1888. var s []byte
  1889. s = read(parser, s)
  1890. /* Copy all subsequent alphabetical and numerical characters. */
  1891. if !cache(parser, 1) {
  1892. return false
  1893. }
  1894. for is_alpha(parser.buffer[parser.buffer_pos]) {
  1895. s = read(parser, s)
  1896. if !cache(parser, 1) {
  1897. return false
  1898. }
  1899. }
  1900. /* Check if the trailing character is '!' and copy it. */
  1901. if parser.buffer[parser.buffer_pos] == '!' {
  1902. s = read(parser, s)
  1903. } else {
  1904. /*
  1905. * It's either the '!' tag or not really a tag handle. If it's a %TAG
  1906. * directive, it's an error. If it's a tag token, it must be a part of
  1907. * URI.
  1908. */
  1909. if directive && !(s[0] == '!' && len(s) == 1) {
  1910. yaml_parser_set_scanner_tag_error(parser, directive,
  1911. start_mark, "did not find expected '!'")
  1912. return false
  1913. }
  1914. }
  1915. *handle = s
  1916. return true
  1917. }
  1918. /*
  1919. * Scan a tag.
  1920. */
  1921. func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool,
  1922. head []byte, start_mark YAML_mark_t, uri *[]byte) bool {
  1923. var s []byte
  1924. /*
  1925. * Copy the head if needed.
  1926. *
  1927. * Note that we don't copy the leading '!' character.
  1928. */
  1929. if len(head) > 1 {
  1930. s = append(s, head[1:]...)
  1931. }
  1932. /* Scan the tag. */
  1933. if !cache(parser, 1) {
  1934. return false
  1935. }
  1936. /*
  1937. * The set of characters that may appear in URI is as follows:
  1938. *
  1939. * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
  1940. * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
  1941. * '%'.
  1942. */
  1943. b := parser.buffer[parser.buffer_pos]
  1944. for is_alpha(b) || b == ';' ||
  1945. b == '/' || b == '?' ||
  1946. b == ':' || b == '@' ||
  1947. b == '&' || b == '=' ||
  1948. b == '+' || b == '$' ||
  1949. b == ',' || b == '.' ||
  1950. b == '!' || b == '~' ||
  1951. b == '*' || b == '\'' ||
  1952. b == '(' || b == ')' ||
  1953. b == '[' || b == ']' ||
  1954. b == '%' {
  1955. /* Check if it is a URI-escape sequence. */
  1956. if b == '%' {
  1957. if !yaml_parser_scan_uri_escapes(parser,
  1958. directive, start_mark, &s) {
  1959. return false
  1960. }
  1961. } else {
  1962. s = read(parser, s)
  1963. }
  1964. if !cache(parser, 1) {
  1965. return false
  1966. }
  1967. b = parser.buffer[parser.buffer_pos]
  1968. }
  1969. /* Check if the tag is non-empty. */
  1970. if len(s) == 0 {
  1971. yaml_parser_set_scanner_tag_error(parser, directive,
  1972. start_mark, "did not find expected tag URI")
  1973. return false
  1974. }
  1975. *uri = s
  1976. return true
  1977. }
  1978. /*
  1979. * Decode an URI-escape sequence corresponding to a single UTF-8 character.
  1980. */
  1981. func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool,
  1982. start_mark YAML_mark_t, s *[]byte) bool {
  1983. /* Decode the required number of characters. */
  1984. w := 10
  1985. for w > 0 {
  1986. /* Check for a URI-escaped octet. */
  1987. if !cache(parser, 3) {
  1988. return false
  1989. }
  1990. if !(parser.buffer[parser.buffer_pos] == '%' &&
  1991. is_hex(parser.buffer[parser.buffer_pos+1]) &&
  1992. is_hex(parser.buffer[parser.buffer_pos+2])) {
  1993. return yaml_parser_set_scanner_tag_error(parser, directive,
  1994. start_mark, "did not find URI escaped octet")
  1995. }
  1996. /* Get the octet. */
  1997. octet := byte((as_hex(parser.buffer[parser.buffer_pos+1]) << 4) +
  1998. as_hex(parser.buffer[parser.buffer_pos+2]))
  1999. /* If it is the leading octet, determine the length of the UTF-8 sequence. */
  2000. if w == 10 {
  2001. w = width(octet)
  2002. if w == 0 {
  2003. return yaml_parser_set_scanner_tag_error(parser, directive,
  2004. start_mark, "found an incorrect leading UTF-8 octet")
  2005. }
  2006. } else {
  2007. /* Check if the trailing octet is correct. */
  2008. if (octet & 0xC0) != 0x80 {
  2009. return yaml_parser_set_scanner_tag_error(parser, directive,
  2010. start_mark, "found an incorrect trailing UTF-8 octet")
  2011. }
  2012. }
  2013. /* Copy the octet and move the pointers. */
  2014. *s = append(*s, octet)
  2015. skip(parser)
  2016. skip(parser)
  2017. skip(parser)
  2018. w--
  2019. }
  2020. return true
  2021. }
  2022. /*
  2023. * Scan a block scalar.
  2024. */
  2025. func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t,
  2026. literal bool) bool {
  2027. /* Eat the indicator '|' or '>'. */
  2028. start_mark := parser.mark
  2029. skip(parser)
  2030. /* Scan the additional block scalar indicators. */
  2031. if !cache(parser, 1) {
  2032. return false
  2033. }
  2034. /* Check for a chomping indicator. */
  2035. chomping := 0
  2036. increment := 0
  2037. if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
  2038. /* Set the chomping method and eat the indicator. */
  2039. if parser.buffer[parser.buffer_pos] == '+' {
  2040. chomping = +1
  2041. } else {
  2042. chomping = -1
  2043. }
  2044. skip(parser)
  2045. /* Check for an indentation indicator. */
  2046. if !cache(parser, 1) {
  2047. return false
  2048. }
  2049. if is_digit(parser.buffer[parser.buffer_pos]) {
  2050. /* Check that the indentation is greater than 0. */
  2051. if parser.buffer[parser.buffer_pos] == '0' {
  2052. yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
  2053. start_mark, "found an indentation indicator equal to 0")
  2054. return false
  2055. }
  2056. /* Get the indentation level and eat the indicator. */
  2057. increment = as_digit(parser.buffer[parser.buffer_pos])
  2058. skip(parser)
  2059. }
  2060. } else if is_digit(parser.buffer[parser.buffer_pos]) {
  2061. /* Do the same as above, but in the opposite order. */
  2062. if parser.buffer[parser.buffer_pos] == '0' {
  2063. yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
  2064. start_mark, "found an indentation indicator equal to 0")
  2065. return false
  2066. }
  2067. increment = as_digit(parser.buffer[parser.buffer_pos])
  2068. skip(parser)
  2069. if !cache(parser, 1) {
  2070. return false
  2071. }
  2072. if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
  2073. if parser.buffer[parser.buffer_pos] == '+' {
  2074. chomping = +1
  2075. } else {
  2076. chomping = -1
  2077. }
  2078. skip(parser)
  2079. }
  2080. }
  2081. /* Eat whitespaces and comments to the end of the line. */
  2082. if !cache(parser, 1) {
  2083. return false
  2084. }
  2085. for is_blank(parser.buffer[parser.buffer_pos]) {
  2086. skip(parser)
  2087. if !cache(parser, 1) {
  2088. return false
  2089. }
  2090. }
  2091. if parser.buffer[parser.buffer_pos] == '#' {
  2092. for !is_breakz_at(parser.buffer, parser.buffer_pos) {
  2093. skip(parser)
  2094. if !cache(parser, 1) {
  2095. return false
  2096. }
  2097. }
  2098. }
  2099. /* Check if we are at the end of the line. */
  2100. if !is_breakz_at(parser.buffer, parser.buffer_pos) {
  2101. yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
  2102. start_mark, "did not find expected comment or line break")
  2103. return false
  2104. }
  2105. /* Eat a line break. */
  2106. if is_break_at(parser.buffer, parser.buffer_pos) {
  2107. if !cache(parser, 2) {
  2108. return false
  2109. }
  2110. skip_line(parser)
  2111. }
  2112. end_mark := parser.mark
  2113. /* Set the indentation level if it was specified. */
  2114. indent := 0
  2115. if increment > 0 {
  2116. if parser.indent >= 0 {
  2117. indent = parser.indent + increment
  2118. } else {
  2119. indent = increment
  2120. }
  2121. }
  2122. /* Scan the leading line breaks and determine the indentation level if needed. */
  2123. var trailing_breaks []byte
  2124. if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks,
  2125. start_mark, &end_mark) {
  2126. return false
  2127. }
  2128. /* Scan the block scalar content. */
  2129. if !cache(parser, 1) {
  2130. return false
  2131. }
  2132. var s []byte
  2133. var leading_break []byte
  2134. leading_blank := false
  2135. trailing_blank := false
  2136. for parser.mark.column == indent && !is_z(parser.buffer[parser.buffer_pos]) {
  2137. /*
  2138. * We are at the beginning of a non-empty line.
  2139. */
  2140. /* Is it a trailing whitespace? */
  2141. trailing_blank = is_blank(parser.buffer[parser.buffer_pos])
  2142. /* Check if we need to fold the leading line break. */
  2143. if !literal && len(leading_break) > 0 && leading_break[0] == '\n' &&
  2144. !leading_blank && !trailing_blank {
  2145. /* Do we need to join the lines by space? */
  2146. if len(trailing_breaks) == 0 {
  2147. s = append(s, ' ')
  2148. }
  2149. leading_break = leading_break[:0]
  2150. } else {
  2151. s = append(s, leading_break...)
  2152. leading_break = leading_break[:0]
  2153. }
  2154. /* Append the remaining line breaks. */
  2155. s = append(s, trailing_breaks...)
  2156. trailing_breaks = trailing_breaks[:0]
  2157. /* Is it a leading whitespace? */
  2158. leading_blank = is_blank(parser.buffer[parser.buffer_pos])
  2159. /* Consume the current line. */
  2160. for !is_breakz_at(parser.buffer, parser.buffer_pos) {
  2161. s = read(parser, s)
  2162. if !cache(parser, 1) {
  2163. return false
  2164. }
  2165. }
  2166. /* Consume the line break. */
  2167. if !cache(parser, 2) {
  2168. return false
  2169. }
  2170. leading_break = read_line(parser, leading_break)
  2171. /* Eat the following indentation spaces and line breaks. */
  2172. if !yaml_parser_scan_block_scalar_breaks(parser,
  2173. &indent, &trailing_breaks, start_mark, &end_mark) {
  2174. return false
  2175. }
  2176. }
  2177. /* Chomp the tail. */
  2178. if chomping != -1 {
  2179. s = append(s, leading_break...)
  2180. }
  2181. if chomping == 1 {
  2182. s = append(s, trailing_breaks...)
  2183. }
  2184. /* Create a token. */
  2185. *token = yaml_token_t{
  2186. token_type: yaml_SCALAR_TOKEN,
  2187. start_mark: start_mark,
  2188. end_mark: end_mark,
  2189. value: s,
  2190. style: yaml_LITERAL_SCALAR_STYLE,
  2191. }
  2192. if !literal {
  2193. token.style = yaml_FOLDED_SCALAR_STYLE
  2194. }
  2195. return true
  2196. }
  2197. /*
  2198. * Scan indentation spaces and line breaks for a block scalar. Determine the
  2199. * indentation level if needed.
  2200. */
  2201. func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t,
  2202. indent *int, breaks *[]byte,
  2203. start_mark YAML_mark_t, end_mark *YAML_mark_t) bool {
  2204. *end_mark = parser.mark
  2205. /* Eat the indentation spaces and line breaks. */
  2206. max_indent := 0
  2207. for {
  2208. /* Eat the indentation spaces. */
  2209. if !cache(parser, 1) {
  2210. return false
  2211. }
  2212. for (*indent == 0 || parser.mark.column < *indent) &&
  2213. is_space(parser.buffer[parser.buffer_pos]) {
  2214. skip(parser)
  2215. if !cache(parser, 1) {
  2216. return false
  2217. }
  2218. }
  2219. if parser.mark.column > max_indent {
  2220. max_indent = parser.mark.column
  2221. }
  2222. /* Check for a tab character messing the indentation. */
  2223. if (*indent == 0 || parser.mark.column < *indent) &&
  2224. is_tab(parser.buffer[parser.buffer_pos]) {
  2225. return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
  2226. start_mark, "found a tab character where an indentation space is expected")
  2227. }
  2228. /* Have we found a non-empty line? */
  2229. if !is_break_at(parser.buffer, parser.buffer_pos) {
  2230. break
  2231. }
  2232. /* Consume the line break. */
  2233. if !cache(parser, 2) {
  2234. return false
  2235. }
  2236. *breaks = read_line(parser, *breaks)
  2237. *end_mark = parser.mark
  2238. }
  2239. /* Determine the indentation level if needed. */
  2240. if *indent == 0 {
  2241. *indent = max_indent
  2242. if *indent < parser.indent+1 {
  2243. *indent = parser.indent + 1
  2244. }
  2245. if *indent < 1 {
  2246. *indent = 1
  2247. }
  2248. }
  2249. return true
  2250. }
  2251. /*
  2252. * Scan a quoted scalar.
  2253. */
  2254. func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t,
  2255. single bool) bool {
  2256. /* Eat the left quote. */
  2257. start_mark := parser.mark
  2258. skip(parser)
  2259. /* Consume the content of the quoted scalar. */
  2260. var s []byte
  2261. var leading_break []byte
  2262. var trailing_breaks []byte
  2263. var whitespaces []byte
  2264. for {
  2265. /* Check that there are no document indicators at the beginning of the line. */
  2266. if !cache(parser, 4) {
  2267. return false
  2268. }
  2269. if parser.mark.column == 0 &&
  2270. ((parser.buffer[parser.buffer_pos] == '-' &&
  2271. parser.buffer[parser.buffer_pos+1] == '-' &&
  2272. parser.buffer[parser.buffer_pos+2] == '-') ||
  2273. (parser.buffer[parser.buffer_pos] == '.' &&
  2274. parser.buffer[parser.buffer_pos+1] == '.' &&
  2275. parser.buffer[parser.buffer_pos+2] == '.')) &&
  2276. is_blankz_at(parser.buffer, parser.buffer_pos+3) {
  2277. yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
  2278. start_mark, "found unexpected document indicator")
  2279. return false
  2280. }
  2281. /* Check for EOF. */
  2282. if is_z(parser.buffer[parser.buffer_pos]) {
  2283. yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
  2284. start_mark, "found unexpected end of stream")
  2285. return false
  2286. }
  2287. /* Consume non-blank characters. */
  2288. if !cache(parser, 2) {
  2289. return false
  2290. }
  2291. leading_blanks := false
  2292. for !is_blankz_at(parser.buffer, parser.buffer_pos) {
  2293. /* Check for an escaped single quote. */
  2294. if single && parser.buffer[parser.buffer_pos] == '\'' &&
  2295. parser.buffer[parser.buffer_pos+1] == '\'' {
  2296. // Is is an escaped single quote.
  2297. s = append(s, '\'')
  2298. skip(parser)
  2299. skip(parser)
  2300. } else if single && parser.buffer[parser.buffer_pos] == '\'' {
  2301. /* Check for the right quote. */
  2302. break
  2303. } else if !single && parser.buffer[parser.buffer_pos] == '"' {
  2304. /* Check for the right quote. */
  2305. break
  2306. } else if !single && parser.buffer[parser.buffer_pos] == '\\' &&
  2307. is_break_at(parser.buffer, parser.buffer_pos+1) {
  2308. /* Check for an escaped line break. */
  2309. if !cache(parser, 3) {
  2310. return false
  2311. }
  2312. skip(parser)
  2313. skip_line(parser)
  2314. leading_blanks = true
  2315. break
  2316. } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
  2317. /* Check for an escape sequence. */
  2318. code_length := 0
  2319. /* Check the escape character. */
  2320. switch parser.buffer[parser.buffer_pos+1] {
  2321. case '0':
  2322. s = append(s, 0)
  2323. case 'a':
  2324. s = append(s, '\x07')
  2325. case 'b':
  2326. s = append(s, '\x08')
  2327. case 't', '\t':
  2328. s = append(s, '\x09')
  2329. case 'n':
  2330. s = append(s, '\x0A')
  2331. case 'v':
  2332. s = append(s, '\x0B')
  2333. case 'f':
  2334. s = append(s, '\x0C')
  2335. case 'r':
  2336. s = append(s, '\x0D')
  2337. case 'e':
  2338. s = append(s, '\x1B')
  2339. case ' ':
  2340. s = append(s, '\x20')
  2341. case '"':
  2342. s = append(s, '"')
  2343. case '/':
  2344. s = append(s, '/')
  2345. case '\\':
  2346. s = append(s, '\\')
  2347. case 'N': /* NEL (#x85) */
  2348. s = append(s, '\xC2')
  2349. s = append(s, '\x85')
  2350. case '_': /* #xA0 */
  2351. s = append(s, '\xC2')
  2352. s = append(s, '\xA0')
  2353. case 'L': /* LS (#x2028) */
  2354. s = append(s, '\xE2')
  2355. s = append(s, '\x80')
  2356. s = append(s, '\xA8')
  2357. case 'P': /* PS (#x2029) */
  2358. s = append(s, '\xE2')
  2359. s = append(s, '\x80')
  2360. s = append(s, '\xA9')
  2361. case 'x':
  2362. code_length = 2
  2363. case 'u':
  2364. code_length = 4
  2365. case 'U':
  2366. code_length = 8
  2367. default:
  2368. yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
  2369. start_mark, "found unknown escape character")
  2370. return false
  2371. }
  2372. skip(parser)
  2373. skip(parser)
  2374. /* Consume an arbitrary escape code. */
  2375. if code_length > 0 {
  2376. value := 0
  2377. /* Scan the character value. */
  2378. if !cache(parser, code_length) {
  2379. return false
  2380. }
  2381. for k := 0; k < code_length; k++ {
  2382. if !is_hex(parser.buffer[parser.buffer_pos+k]) {
  2383. yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
  2384. start_mark, "did not find expected hexdecimal number")
  2385. return false
  2386. }
  2387. value = (value << 4) + as_hex(parser.buffer[parser.buffer_pos+k])
  2388. }
  2389. /* Check the value and write the character. */
  2390. if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
  2391. yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
  2392. start_mark, "found invalid Unicode character escape code")
  2393. return false
  2394. }
  2395. if value <= 0x7F {
  2396. s = append(s, byte(value))
  2397. } else if value <= 0x7FF {
  2398. s = append(s, byte(0xC0+(value>>6)))
  2399. s = append(s, byte(0x80+(value&0x3F)))
  2400. } else if value <= 0xFFFF {
  2401. s = append(s, byte(0xE0+(value>>12)))
  2402. s = append(s, byte(0x80+((value>>6)&0x3F)))
  2403. s = append(s, byte(0x80+(value&0x3F)))
  2404. } else {
  2405. s = append(s, byte(0xF0+(value>>18)))
  2406. s = append(s, byte(0x80+((value>>12)&0x3F)))
  2407. s = append(s, byte(0x80+((value>>6)&0x3F)))
  2408. s = append(s, byte(0x80+(value&0x3F)))
  2409. }
  2410. /* Advance the pointer. */
  2411. for k := 0; k < code_length; k++ {
  2412. skip(parser)
  2413. }
  2414. }
  2415. } else {
  2416. /* It is a non-escaped non-blank character. */
  2417. s = read(parser, s)
  2418. }
  2419. if !cache(parser, 2) {
  2420. return false
  2421. }
  2422. }
  2423. /* Check if we are at the end of the scalar. */
  2424. b := parser.buffer[parser.buffer_pos]
  2425. if single {
  2426. if b == '\'' {
  2427. break
  2428. }
  2429. } else if b == '"' {
  2430. break
  2431. }
  2432. /* Consume blank characters. */
  2433. if !cache(parser, 1) {
  2434. return false
  2435. }
  2436. for is_blank(parser.buffer[parser.buffer_pos]) || is_break_at(parser.buffer, parser.buffer_pos) {
  2437. if is_blank(parser.buffer[parser.buffer_pos]) {
  2438. /* Consume a space or a tab character. */
  2439. if !leading_blanks {
  2440. whitespaces = read(parser, whitespaces)
  2441. } else {
  2442. skip(parser)
  2443. }
  2444. } else {
  2445. if !cache(parser, 2) {
  2446. return false
  2447. }
  2448. /* Check if it is a first line break. */
  2449. if !leading_blanks {
  2450. whitespaces = whitespaces[:0]
  2451. leading_break = read_line(parser, leading_break)
  2452. leading_blanks = true
  2453. } else {
  2454. trailing_breaks = read_line(parser, trailing_breaks)
  2455. }
  2456. }
  2457. if !cache(parser, 1) {
  2458. return false
  2459. }
  2460. }
  2461. /* Join the whitespaces or fold line breaks. */
  2462. if leading_blanks {
  2463. /* Do we need to fold line breaks? */
  2464. if len(leading_break) > 0 && leading_break[0] == '\n' {
  2465. if len(trailing_breaks) == 0 {
  2466. s = append(s, ' ')
  2467. } else {
  2468. s = append(s, trailing_breaks...)
  2469. trailing_breaks = trailing_breaks[:0]
  2470. }
  2471. leading_break = leading_break[:0]
  2472. } else {
  2473. s = append(s, leading_break...)
  2474. s = append(s, trailing_breaks...)
  2475. leading_break = leading_break[:0]
  2476. trailing_breaks = trailing_breaks[:0]
  2477. }
  2478. } else {
  2479. s = append(s, whitespaces...)
  2480. whitespaces = whitespaces[:0]
  2481. }
  2482. }
  2483. /* Eat the right quote. */
  2484. skip(parser)
  2485. end_mark := parser.mark
  2486. /* Create a token. */
  2487. *token = yaml_token_t{
  2488. token_type: yaml_SCALAR_TOKEN,
  2489. start_mark: start_mark,
  2490. end_mark: end_mark,
  2491. value: s,
  2492. style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
  2493. }
  2494. if !single {
  2495. token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
  2496. }
  2497. return true
  2498. }
  2499. /*
  2500. * Scan a plain scalar.
  2501. */
  2502. func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
  2503. var s []byte
  2504. var leading_break []byte
  2505. var trailing_breaks []byte
  2506. var whitespaces []byte
  2507. leading_blanks := false
  2508. indent := parser.indent + 1
  2509. start_mark := parser.mark
  2510. end_mark := parser.mark
  2511. /* Consume the content of the plain scalar. */
  2512. for {
  2513. /* Check for a document indicator. */
  2514. if !cache(parser, 4) {
  2515. return false
  2516. }
  2517. if parser.mark.column == 0 &&
  2518. ((parser.buffer[parser.buffer_pos] == '-' &&
  2519. parser.buffer[parser.buffer_pos+1] == '-' &&
  2520. parser.buffer[parser.buffer_pos+2] == '-') ||
  2521. (parser.buffer[parser.buffer_pos] == '.' &&
  2522. parser.buffer[parser.buffer_pos+1] == '.' &&
  2523. parser.buffer[parser.buffer_pos+2] == '.')) &&
  2524. is_blankz_at(parser.buffer, parser.buffer_pos+3) {
  2525. break
  2526. }
  2527. /* Check for a comment. */
  2528. if parser.buffer[parser.buffer_pos] == '#' {
  2529. break
  2530. }
  2531. /* Consume non-blank characters. */
  2532. for !is_blankz_at(parser.buffer, parser.buffer_pos) {
  2533. /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
  2534. if parser.flow_level > 0 &&
  2535. parser.buffer[parser.buffer_pos] == ':' &&
  2536. !is_blankz_at(parser.buffer, parser.buffer_pos+1) {
  2537. yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
  2538. start_mark, "found unexpected ':'")
  2539. return false
  2540. }
  2541. /* Check for indicators that may end a plain scalar. */
  2542. b := parser.buffer[parser.buffer_pos]
  2543. if (b == ':' && is_blankz_at(parser.buffer, parser.buffer_pos+1)) ||
  2544. (parser.flow_level > 0 &&
  2545. (b == ',' || b == ':' ||
  2546. b == '?' || b == '[' ||
  2547. b == ']' || b == '{' ||
  2548. b == '}')) {
  2549. break
  2550. }
  2551. /* Check if we need to join whitespaces and breaks. */
  2552. if leading_blanks || len(whitespaces) > 0 {
  2553. if leading_blanks {
  2554. /* Do we need to fold line breaks? */
  2555. if leading_break[0] == '\n' {
  2556. if len(trailing_breaks) == 0 {
  2557. s = append(s, ' ')
  2558. } else {
  2559. s = append(s, trailing_breaks...)
  2560. trailing_breaks = trailing_breaks[:0]
  2561. }
  2562. leading_break = leading_break[:0]
  2563. } else {
  2564. s = append(s, leading_break...)
  2565. s = append(s, trailing_breaks...)
  2566. leading_break = leading_break[:0]
  2567. trailing_breaks = trailing_breaks[:0]
  2568. }
  2569. leading_blanks = false
  2570. } else {
  2571. s = append(s, whitespaces...)
  2572. whitespaces = whitespaces[:0]
  2573. }
  2574. }
  2575. /* Copy the character. */
  2576. s = read(parser, s)
  2577. end_mark = parser.mark
  2578. if !cache(parser, 2) {
  2579. return false
  2580. }
  2581. }
  2582. /* Is it the end? */
  2583. if !(is_blank(parser.buffer[parser.buffer_pos]) ||
  2584. is_break_at(parser.buffer, parser.buffer_pos)) {
  2585. break
  2586. }
  2587. /* Consume blank characters. */
  2588. if !cache(parser, 1) {
  2589. return false
  2590. }
  2591. for is_blank(parser.buffer[parser.buffer_pos]) ||
  2592. is_break_at(parser.buffer, parser.buffer_pos) {
  2593. if is_blank(parser.buffer[parser.buffer_pos]) {
  2594. /* Check for tab character that abuse indentation. */
  2595. if leading_blanks && parser.mark.column < indent &&
  2596. is_tab(parser.buffer[parser.buffer_pos]) {
  2597. yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
  2598. start_mark, "found a tab character that violate indentation")
  2599. return false
  2600. }
  2601. /* Consume a space or a tab character. */
  2602. if !leading_blanks {
  2603. whitespaces = read(parser, whitespaces)
  2604. } else {
  2605. skip(parser)
  2606. }
  2607. } else {
  2608. if !cache(parser, 2) {
  2609. return false
  2610. }
  2611. /* Check if it is a first line break. */
  2612. if !leading_blanks {
  2613. whitespaces = whitespaces[:0]
  2614. leading_break = read_line(parser, leading_break)
  2615. leading_blanks = true
  2616. } else {
  2617. trailing_breaks = read_line(parser, trailing_breaks)
  2618. }
  2619. }
  2620. if !cache(parser, 1) {
  2621. return false
  2622. }
  2623. }
  2624. /* Check indentation level. */
  2625. if parser.flow_level == 0 && parser.mark.column < indent {
  2626. break
  2627. }
  2628. }
  2629. /* Create a token. */
  2630. *token = yaml_token_t{
  2631. token_type: yaml_SCALAR_TOKEN,
  2632. start_mark: start_mark,
  2633. end_mark: end_mark,
  2634. value: s,
  2635. style: yaml_PLAIN_SCALAR_STYLE,
  2636. }
  2637. /* Note that we change the 'simple_key_allowed' flag. */
  2638. if leading_blanks {
  2639. parser.simple_key_allowed = true
  2640. }
  2641. return true
  2642. }