- 1. Úvod
- 2. Režimy parsování
- 3. Pravidla dialektu Parse
- 4. Události procesu parse
- 5. Extra funkce
- 6. Implementační poznámky
- 7. Poznámka k překladu
Dialekt Parse je vnořený DSL (domain-specific language) programovacího jazyka Red, který umožňuje stručné a přesné porovnání vstupních řad se zadanými gramatickými pravidly. Obecná pravidla tohoto dialektu jsou:
-
Hledání - lokalizace zadaných vzorů
-
Validace - ověření shody vstupu s určitou specifikací
-
Vyjmutí - přefiltrování dat a agregace hodnot (e.g. scraping)
-
Modifikace - transformace dat (vložení či odejmutí hodnot a změna detekovaných částí vstupů)
-
Zpracování jazyka - použití kompilátorů, interpretů a lexikálních analyzátorů, zvláště pro DSL
-
Kódování a dekódování - konverze datových formátů z jednoho do druhého.
Proces parsování se invokuje funkcí parse s použitím jednoduché skladby (podrobněji viz sekce Extra funkce):
parse <input> <rules> <input> : jakákoli hodnota typu series! kromě image! a vector! <rules> : hodnota typu block!, obsahující platný dialekt Parse (top-level rule)
Funkce parse
vrací hodnotu typu logic!
jako sdělení, zda zadaná gramatická pravidla byla či nebyla v úplné shodě se zadanými částmi vstupu.
Gramatická pravidla definují vzory, použité pro vyhodnocení vstupních dat. Základní hodnotící krok dialektu Parse je pravidlo match, které má jeden z těchto dvou výstupů:
-
Pokud se zadané pravidlo shoduje s posuzovanou částí vstupu, je úspěšné a proces parse postoupí (advance) za konformní část vstupu (i pravidla);
-
Pokud se neshoduje, pravidlo selhává (fails), načež se parse vrátí (backtracks) k alternativním pravidlům - pokud existují.
Hodnocení vstupu (parsing) je stále se opakující aplikace tohoto základního kroku, která je zastavena jednou z následujících dvou ukončujících podmínek:
-
Neúspěšná aplikace pravidla:
parse
vracífalse
, signalizujíce neshodu -
Úplná shoda pravidla s porovnávaným vstupem a vyčerpání vstupu (to jest dosažení konce zkoumaného vstupu):
parse
vracítrue
, signalizujíce shodu.
Caution
|
Nejsou-li splněny ukončovací podmínky, může vstoupit Parse do nekonečné smyčky. |
Dialekt parse je vylepšený člen rodiny formálních jazyků Parsing Expression Grammar (PEG), odlišující se širokou sadou vlastností a hlubokou integrací s jazykem Red, avšak sdílející obecné významy základních konstrukcí a operací:
- Gramatická pravidla
-
Hierarchické výrazy s prakticky neomezenou skladebností. Jejich skladba a sémantika jsou popsány v sekci Pravidla dialektu Parse.
- Postupování
-
Procházení (advancing) vstupní řadou postupným ověřováním shody jednotlivého elementu s gramatickými pravidly - až ke konci řady nebo k výskytu neshody.
- Vyhledání
-
Hledání následně použitelného pravidla pro uplatnění za úspěšnou shodou (fetching).
- Alternace (v PEG popsáno jako uspořádaný výběr)
-
V případě neshody s pravidlem se postupně pokoušet o shodu s alternativními pravidly v témže bloku za znakem
|
("pipe", "bar", "or else"). - Navrácení (backtracking)
-
Obnovení vstupu a pravidel na pozici před selháním pravidla. Ostatní změny (vedlejší účinky a úpravy vstupu či pravidel) zůstávají.
- Possesive matching
-
Parsovací pravidla (zejména Opakování) se vždycky snaží posoudit co nejvíce vstupních dat.
Procedura parse nabízí určitou flexibilitu provedení podporou různých režimů.
Implicitně má Parse shodnou sémantiku jako Red a je case-insensitive. Rozlišení velkých písmen lze zapnout upřesněním /case
a zapnout či vypnout klíčovým slovem case
. Slovo case
mění režim srovnávání jenom pro následující pravidlo a poté jej vrací zpět nezávisle na úspěch či neúspěch (failure) pravidla.
Syntaxe
case <word> <word> : word! value
S hodnotou, na níž odkazuje word se zachází jako s logickým praporkem (flag) podle standardní sémantiky Redu. Logické true
umožňuje case-sensitivní režim, zatímco logické false
jej znemožňuje.
Pravidlo collect
přikazuje, aby parse
vrátilo blok místo hodnoty logic!
. Detaily lze nalézt v sekci Vyjmutí.
V závislosti na typu vstupních dat nejsou některá pravidla Parse uplatnitelná nebo se chovají odlišně.
-
any-block!
: porovnávání se sadou znaků nemá žádný význam a vždycky selže; -
any-string!
: porovnávání s datovým typem nebo sadou typů není podporováno. -
binary!
: porovnávání s datovým typem nebo sadou typů je podporováno pro hodnoty s kódováním UTF-8; takové porovnáníá je úspěšné, pokud porovnávané části vstupu reprezentují některou z literálových forem datového typu. Prázdné znaky před tokeny jsou automaticky přeskočeny.
Příklad
parse to binary! "3 words: matching by datatype" [number! set-word! 3 word!]
Gramatická pravidla v dialektu Parse mohou mít několik forem a obvykle mají vnořenou nebo rekurzivní strukturu. Každé pravidlo je jedním z následujících:
-
Dialektem rezervované klíčové slovo, volitelně následované argumenty nebo možnostmi (viz níže).
-
Hodnota některého z následujících datových typů:
-
datatype!
nebotypeset!
- porovnává vstupní hodnotu s jejím typem; -
bitset!
- reprezentuje znakovou sadu; -
word!
- odkazuje na well-formed sub-pravidlo; -
lit-word!
nebolit-path!
— zavedené zkratky pro parsování vstupních hodnot typuword!
případněpath!
; -
set-word!
- se používá k nastavení slova na aktuální vstupní pozici; -
get-word!
- vrátí pozici vstupu k místu, označeném slovem; -
block!
- hodnota, která obsahuje libovolný počet sub-pravidel a znaků|
, jež působí jako oddělovače pro alternativní pravidla; -
integer!
- hodnota, která slouží jako počítadlo pro opakování pravidla; dvě následující hodnoty typuinteger!
označují rozsah možných iterací; -
paren!
- hodnota, která působí jako únikový mechanizmus dialektu vyhodnocením obsaženého výrazu Red a pokračováním v parsování vstupu; některá klíčová slova Parse používají vrácené hodnoty z výrazu ve shodě se svou vlastní sémantikou;
-
-
Jakákoliv jiná literálová hodnota výše nezmíněná, jež se používá tak jak je pro přímé porovnávání se vstupem.
Note
|
Parse je konsistentní s Redem v používání volného přirovnání pro porovnávání s literálovými hodnotami. |
Každé pravidlo (rule) je charakterizováno podmínkami, při kterých parsování pokročí vstupem a uspěje. Přehled pravidel (jak vyhražená, tak klíčová slova) je tabelárně uveden níže.
Pravidlo | Categorie | Pokročí | Uspěje |
---|---|---|---|
|
Never |
Always |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
literal value |
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Never |
Always |
|
|
Never |
Depends |
|
|
Depends |
Always |
|
|
Never |
Depends |
|
|
Never |
Depends |
|
|
Never |
Always |
|
|
Never |
Always |
|
|
Depends |
Always |
|
|
Depends |
Depends |
|
|
Depends |
Always |
|
|
Depends |
Depends |
|
|
Depends |
Always |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Never |
Depends |
|
|
Depends |
Depends |
|
|
Never |
Never |
|
|
Never |
Always |
|
|
Never |
Never |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Depends |
Depends |
|
|
Always |
Always |
|
|
Depends |
Depends |
Tip
|
Všechna pravidla v dále uvedených odstavcích se plně shodují se svými vstupy. |
Pravidla block!
přímo seskupují ostatní prvidla, jsouce prostředkem pro kombinaci. Pravidla word!
nepřímo odkazují na jiná pravidla, jsouce tak prostředkem abstrakce. Společně tvoří základ mluvnické skladby dialektu Parse.
Na strukturální úrovni je gramatika dialektu Parse složena ze sekvencí a alternativ.
-
Sekvence pravidel je skupina nula či více pravidel, individuelně ukončených koncem sekvence. Tato sekvence je úspěšná, dospěje-li parsování (postupně úspěšnou aplikací svých sub-pravidel) ke svému konci. V případě selhání některého sub-pravidla se proces vrátí (backtracks) na počátek neúspěšné sekvence.
-
Koncem sekvence pravidel je buď konec vymezujícího bloku nebo hraniční znak
|
alternativy. -
Alternativa je volitelná sekvence, kterou se Parse pokusí posoudit v případě, že předchozí (to jest před hranicí
|
) sekvence selže.
Pravidla, popsaná v této části, přímo posuzují shodu vstupnch dat a slouží jako základní stavební bloky pro sestavování složitějších pravidel.
Posouzení shody literálové hodnoty je úspěšné a vede k pokročení zadaným vstupem, je-li posuzovaná literálová hodnota totožná s hodnotou na aktuální pozici.
Note
|
Parse používá volnou komparaci pro ověření rovnosti. Case-sensitivní režim vynucuje porovnání s rozlišením malých a velkých písmen. |
Příklad
parse [today is 5-September-2012 #"," 20.3 degrees/celsius][ 'yesterday 'was | 'today 'is 05/09/12 comma 2030e-2 ['degrees/fahrenheit | 'degrees/celsius] ]
Note
|
Pro porovnávání literálových hodnot, vymezených v dialektu Parse, se jako únikový mechanizmus používá klíčové slovo |
Ověření shody podle datového typu (datatype) je úspěšné a vede k pokročení vstupem, pokud je ověřovaná hodnota daného typu.
Příklad
parse [#a 'bird /is :the word][issue! lit-word! refinement! get-word! word!]
Note
|
Ověření shody podle datového typu není podporováno pro vstup typu |
Ověření shody podle typové sady (type set) je úspěšné a vede k pokročení vstupem, patří-li datový typ vstupní hodnoty k dané typové sadě.
Příklad
banner: [ | [_] [___] [_____] Red programming language https://www.red-lang.org ] parse banner [default! series! any-block! any-list! all-word! any-word! any-type! any-string!]
Note
|
Ověření shody podle typové sady není podporováno pro vstup typu |
Jsou-li vstupní data typu any-string!
nebo binary!
a vstupní
hodnotu reprezentuje Unicode Code Point (UCP), který patří k dané sadě znaků, je ověření shody úspěšné a vede k posunu vstupem. Ve všech ostatních případech je ověření shody neúspěšné.
Podrobnosti o vytvoření datové sady lze nalézt v
documentaci k datovému typu bitset!
.
Příklad
animal: charset [#"🦢" #"^(1F418)" 128007] follow: charset "🚶👣🚸" parse "👣 the white 🐇" [follow " the white " animal]
Note
|
Varianty lowercase/uppercase téhož písmena mají různá UCP. Z toho vyplývá, že ověřování shody podle znakové sady je case-sensitive bez ohledu na režim parsování. |
Note
|
Pro vstup typu |
Působí jako únikový (escape) mechanizmus ze sémantiky dialektu Parse doslovným ověřením shody následující hodnoty. Toto pravidlo je úspěšné a vede k posunu vstupem, jestliže je ověření shody úspěšné.
Syntaxe
quote <value> <value> : literal value to match
Příklad
parse [[integer!] matches 20][quote [integer!] quote matches quote 20]
Shoduje se s libobolnou hodnotou a pokročí vstupem. Selže pouze v případě, kdy je pozice vstupu na chvostu (tail), protože tam není co posuzovat.
Příklad
parse <💓> [skip | the beat]
Pravidlo no-op nebo catch-all, vždy se shoduje a nikdy nevede k postupu vstupem.
Příklad
parse reduce [none none][none #(none) ['none | none] none! none]
Pravidla s předstihem (look-ahead) nabízejí podrobnější nastavení pro ověřování shody, couvání (backtracking) a posun vstupu.
Volitelně posuzuje shodu s daným pravidlem, která vede či nevede k posunu vstupem. Pravidlo je vždy úspěšné (== true) bez ohledu na shodu.
Syntaxe
opt <rule> <rule> : Parse rule (option) to match
Příklad
parse "maybe" [opt "or" "may" opt [#"b" #"e"] opt "not"]
Toto pravidlo je úspěšné, jestliže zadané pravidlo selže a opačně. Nikdy nevede k posunu vstupem, bez ohledu na shodu či neshodu.
Syntaxe
not <rule> <rule> : Parse rule to invert
Příklad
parse [panama][not 'man not ['plan | 'canal] not word! | skip]
Pravidlo typu paren!
obsahuje libovolný výraz Redu, který se v případě shody vyhodnotí. Toto pravidlo je vždy úspěšné ale nevede k postupu vstupem.
Příklad
parse [(did it match?)][ block! (not matched) | (probe 'backtracked) quote (did it match?) (probe 'matched!) ]
Je možné označit aktuální pozici vstupu nebo přejít (rewind/fast-forward) na jinou pozici v téže vstupní řadě.
Pravidlo set-word!
nastaví slovo k aktuální pozici vstupní řady. Je vždy úspěšné a nikdy nevede k postupu vstupem.
Příklad
check: quote (probe reduce [start :failed before after current end]) match: [before: 'this none after:] parse [match this input][ start: quote [false start] failed: | ahead [skip match] current: ['match 'this 'input] end: check ]
Pravidlo get-word!
nastaví pozici vstupu do místa, označeného zadaným slovem. Je vždy úspěšné a buď posouvá vpřed, zůstává stát nebo posouvá vzad - v závislosti na postavení markeru vzhledem k aktuální pozici vstupu.
Příklad
phrase: "and so on and so forth, 'til it gets boring" goes: skip find phrase comma 2 end: tail phrase parse phrase [again: "and" :again ['it | :goes] "until the" | :end]
Note
|
Přemístění pozice do jiné řady než vstupní není dovoleno. |
Pravidla níže popsaná působí při posouzení shody jako smyčky nebo iterátory buď určeným počtem opakování nebo až do dosažení neshody.
Note
|
Opakovací pravidla mají vlastnické chování a posoudí shodu co možná nejrozsáhlejšího vstupu. |
Provede posouzení shody s daným pravidlem zadaným počtem opakování. Je-li použita skladba range, je jako úspěšný akceptován libovolný počet shod v zadaném rozsahu.
Syntaxe
<count> <rule> <count> <count> <rule> <count> : non-negative integer! value or word! referring to such value <rule> : Parse rule to match a specified number of times
Note
|
Při použití skladby range musí být první celé číslo (spodní mez) menší nebo roven druhému celému číslu (horní mez). |
Příklad
tuple: [2 word!] triple: [3 skip] THX: 1138 parse [G A T T A C A][2 3 tuple triple | 0 thx [triple tuple] 1 tuple 0 triple]
Pravidla dialektu Parse lze rekurzivně skládat. Úroveň rekurze je limitována hloubkou interní paměti stack.
Příklad
ping: [none pong] pong: [skip ping | end] parse https://google.com ping
Porovná dané pravidlo nula či vícekrát (Kleene star), porovnávání končí při výskytu neshody nebo když nedojde k posunu vstupem. Pravidlo je vždy úspěšné.
Syntaxe
any <rule> <rule> : Parse rule to match zero or more times
Příklad
letter: charset [#"a" - #"z" #"A" - #"Z"] digit: charset [#"0" - #"9"] parse "Wow, 20 horses at 12,000 RPM!" [ any "Twin ceramic rotor drives on each wheel!" "Wow" any [ comma any space any digit space any letter any [not comma skip] ] ]
Porovná dané pravidlo jednou či vícekrát (Kleene plus), porovnávání končí při výskytu neshody nebo když nedojde k posunu vstupem. Pravidlo je úspěšné při nalezení alespoň jedné shody.
Syntaxe
some <rule> <rule> : Parse rule to match one or more times
Příklad
parse [ skidamarink a dink a dink skidamarink a doo ][ some [ some none 'skidamarink [some ['a 'dink] | 'a 'doo] ] ]
Opakovaně porovnává dané pravidlo. Zastaví se pouze po selhání pravidla. Vždycky úspěšné.
POZOR: Jestliže pravidlo neselže, uvízlo while
v nekonečné smyčce.
Syntaxe
while <rule> <rule> : Parse rule to match repeatedly
Příklad
parse [throw for a loop][ while [word! | (print "failed and backtracked on matching the end") [not end] :explicit failure] | [while none] :infinite loop ]
Pravidla této skupiny (search) hledají určený vzor procházejíc vstupem až k výskytu shody.
Opakovaně se pokouší nalézt shodu s daným pravidlem až k dosažení úplné shody. Pokud řečené pravidlo selže, postoupí se vstupem o jeden element, což se počítá jako částečná shoda. V případě úplné shody je pozice vstupu nastavena do čela (head) posuzované části. Succeeds if rule match succeeded.
Syntaxe
to <rule> <rule> : Parse rule (pattern to put input position at)
Příklad
matrix: #{ 416C6C20492073656520697320626C6F6E6465 2C206272756E657474652C201337526564C0DE } parse matrix [ to #{FACEFEED} | to #{1337} #{1337} start: to #{C0DE} end: (print to string! copy/part start end) 2 skip ]
Opakovaně se pokouší nalézt shodu s daným pravidlem až k dosažení úplné shody. Pokud řečené pravidlo selže, postoupí se vstupem o jeden element, což se počítá jako částečná shoda. V případě úplné shody je pozice vstupu nastavena do chvostu (tail) posuzované části. Succeeds if rule match succeeded.
Syntaxe
thru <rule> <rule> : Parse rule (pattern to advance thru)
Příklad
parse 'per/aspera/ad/astra [thru 'aspera ad: to 'astra thru end (probe ad)]
Pravidla této skupiny (control flow) reguluje provedení procesu Parse smyčkami (Opakování), změnou vstupu, předčasným ukončením a podmíněným porovnáním.
Podmíněná shoda - je úspěšná, když se daný výraz Redu vyhodnotí na true. Nikdy se neposune vstupem.
Syntaxe
if <expression> <expression> : paren! expression
Příklad
parse [4 8 15 16 23 42][ some [mark: skip if (any [even? probe mark/1 find [15 23] first mark])] ]
Je-li datový typ hodnoty na aktuální pozici vstupu podporován dialektem Parse, pravidlo into
dočasně přemístí vstup k této hodnotě a posoudí ji z hlediska daného pravidla. Po skončeném posouzení se vstup vrátí do původní pozice a parsování pokračuje za shodující se hodnotou.
Syntaxe
into <rule> <rule> : block! rule or word! that refers to such rule
Příklad
rule: [some [word! | into rule]] parse [we [need [to [go [deeper]]]]] rule
Tento příkaz vynutí neshodu s pravidlem, pokud je umístěn na jeho konci. Nikdy neuspěje ani nepokročí vstupem.
Příklad
parse [email protected] [["quux" | some fail | "foo"] "@" [fail] | thru "bar.baz"]
Vynutí okamžitou shodu aktuálního pravidla block!
. Ukončí průběh smyčky, je-li použito v nejvyšší úrovni opakovacího pravidla. Vždy uspěje a nikdy nepokročí vstupem.
Příklad
parse [break away from everything][some [break] 0 1 [break] [2 [break] | 3 word! [break] skip]]
Vynutí okamžitou neshodu aktuálního pravidla block!
. Ukončí průběh smyčky, je-li použito v nejvyšší úrovni opakovacího pravidla. Nikdy neuspěje a nepokročí vstupem.
Příklad
parse quote (I made a choice that I regret) [ any [reject now] some [5 word! what: reject I see] is | :what 'I [[reject get] | skip] ]
Vyjímací (extraction) pravidla kopírují shodné hodnoty ze vstupních řad.
Přiřadí dané slovo první hodnotě v konformní části vstupu.
Note
|
Slovu je přiřazena hodnota |
Note
|
Pro vstup typu |
Syntaxe
set <word> <rule> <word> : word! value to set <rule> : Parse rule
Příklad
parse "🍩🕳️" [set hole ahead [2 skip] set donut [to end]]
Přiřadí dané slovo kopii shodující se části vstupu.
Note
|
Pokud porovnávané pravidlo nepokročilo vstupem, je slovu přiřazena prázdá řada (series) stejného typu jako vstup. |
Syntaxe
copy <word> <rule> <word> : word! value to set <rule> : Parse rule
Příklad
parse [Huston do you copy?][2 word! copy Huston [2 word!] copy we opt "have a problem"]
Shromáždí konformní hodnoty, které jsou označeny klíčovým slovem keep
. Uspěje, uspěje-li dané pravidlo - postupujíc za konformní (matched) část vstupu.
Pravidlo keep
uspěje, uspěje-li poskytnuté pravidlo - vkládajíc konformní hodnoty do bloku, vymezeného pravidlem collect
.
Note
|
Použití klíčového slova |
Syntaxe
collect <rule> collect set <word> <rule> collect into <word> <rule> collect after <word> <rule> <word> : word! value <rule> : Parse rule
Hodnoty jsou implicitně vkládány do chvostu (tail) bloku. Toto chování lze změnit níže popsanými volbami.
collect
.
Volba | Popis |
---|---|
|
Přiřadí danému slovu blok shromážděných (collected) hodnot. |
|
Vloží shromážděné hodnoty do řady (series), označené slovem, přenese index řady do jejího čela. |
|
Vloží shromážděné hodnoty do řady (series), označené slovem, přemístí index řady za vloženou část. |
-
Je-li v kterémkoli pravidlu použit pokyn
collect
bez volbyinto
čiafter
, vráti funkceparse
blok shromážděných hodnot (viz Režimy parsování); je-li pokyncollect
použit s volbouset
, vrátí funkceparse
hodnotu typulogic!
jako obvykle. -
První použití pokynu
collect
alokuje nový blok, který je vrácen funkcíparse
, každé další použití pokynucollect
alokuje hodnoty (blok) na chvostu (tail) předchozího bloku; pokyncollect
s volbouinto
čiafter
použije již vytvořený buffer spíše než alokaci nového bloku.
Syntaxe pro keep
:
keep <rule> keep pick <rule> keep <expression> keep pick <expression> <rule> : Parse rule <expression> : paren! expression
-
Jestliže porovnávané pravidlo nepokročilo vstupem, příkaz
keep
nic nezadrží. -
Jestliže pravidlo vyčlenilo jedinou hodnotu - tato je zadržena (is kept). Je-li
keep
následováno pravidlemcopy
, potom je posuzovaná hodnota přiřazena stejnému typu z typesetuseries
jako vstup. -
Jestliže pravidlo vyčlenilo více hodnot, jsou tyto seskupeny do objektu stejného typu jako vstup; při volbě
pick
nejsou hodnoty seskupeny ale uchovány odděleně. -
Je-li příkaz
keep
použit s výrazem typuparen!
, je výsledek jeho vyhodnocení uchován tak, jak je.
Example
fruit: charset [#"^(1F346)" - #"^(1F353)"] plate: "tropical stuff: 🍌🍍 and other healthy food: 🥒🍅🥕" parse plate [ collect [ keep (quote fruits:) collect [some [keep fruit | skip] fail] | keep (quote vegetables:) collect [to [#"🥒" | "Pickle Rick!"] keep pick [to end]] ] ]
Akce parse může modifikovat své vstupy vložením nových hodnot a odebrat či změnit odpovídající části vstupu.
Buď odebere část vstupu, konformní s daným pravidlem nebo odebere vstup mezi aktuální a zadanou pozicí; poté zachová aktuální vstupní pozici.
Note
|
Odebírání hodnot je "forward-consuming" operace. Jinými slovy, počítá se jako shoda, přesto že nedojde k pokročení vstupem. |
Syntaxe
remove <rule> remove <word> <rule> : Parse rule <word> : input postion
Příklad
parse [remove me <and me also> "but leave me be"][some [remove word!] mark: to string! remove mark skip]
Vloží literálovou hodnotu nebo výsledek vyhodnocení výrazu buď do aktuální nebo zadané (marked) pozice. Akce je vždy úspěšná a pokročí vstupem za místo vložení, pokud byla provedena v aktuální pozici, jinak je zachována vstupní pozice.
Syntaxe
insert <value> insert <expression> insert <word> <value> insert <word> <expression> insert only <value> insert only <expression> insert only <word> <value> insert only <word> <expression> <word> : input position <value> : literal value <expression> : paren! expression
Je-li literálová hodnota typu word!
, použije se hodnota, na níž slovo odkazuje. Volba only
prosadí sémantiku insert/only
.
Příklad
ikea: [assembly] here: tail ikea parse ikea [ insert only here [🏗️ 🧰👷] insert only (load "[manual]") word! insert ikea [some] block! insert [required] ]
Mění konformní (matched) část vstupu na literálovou hodnotu nebo na výsledek vyhodnocení výrazu. Navíc, může změnit část vstupu mezi aktuální a označenou pozicí. Byla-li změna provedena v aktuální pozici, je úspěšná a posune vstup za upravovanou část; v opačném případě je vstupní pozice zachována.
Syntaxe
change <rule> <value> change <rule> <expression> change <word> <value> change <word> <expression> change only <rule> <value> change only <rule> <expression> change only <word> <value> change only <word> <expression> <rule> : Parse rule <word> : input position <value> : literal value <expression> : paren! expression
Je-li literálová hodnota typu word!
, použije se její odkazovaná hodnota. Volba only
prosadí sémantiku change/only
.
Příklad
parse [some things never change][ change none (quote and) 2 skip mark: to end change only mark [do] ]
Dialekt Parse je implementován jako "pushdown automaton" (PDA), využívající paměti typu stack. Při každé změně stavu emituje událost (event, hodnota typu word!
), která informuje uživatele o parsovacím procesu. Interakce mezi událostmi a interním stavem aktivity parse je dosaženo upřesněním /trace
a "callback" funkcí (viz další odstavec).
Níže je uveden seznam všech událostí s podmínkami, které je vyvolávají (štos = stack):
Událost | Popis |
---|---|
|
Poté co je pravidlo vloženo na štos. |
|
Předtím než je pravidlo staženo ze štosu. |
|
Předtím než je přiřazeno nové pravidlo. |
|
Poté co byla nalezena shoda hodnoty s pravidlem. |
|
Po započetí nového iteračního kola (viz Opakování). |
|
Po vyhodnocení výrazu typu |
|
Po dosažení konce vstupu. |
Vstupním bodem do dialektu Parse je nativní funkce parse
, která přijme vstupní objekt typu series!, blok s pravidly a která podporuje dodatečná upřesnění (refinements):
parse
refinements.
Refinement | Description |
---|---|
|
Umožnit case-sensitive režim. |
|
Limitovat parsování určenou délkou nebo pozicí vstupu. |
|
Spolupůsobit s rozhraním PDA přes zadaný callback. |
Při použití upřesnění /trace
musí být určena funkce "zpětného volání " (callback, hodnota typu function!
) s následující specifikací:
Argument | Type | Description |
---|---|---|
|
|
Některá z Události procesu parse. |
|
|
Výsledek poslední shody |
|
|
Aktuální pravidlo v aktuální pozici. |
|
|
Vstupní objekt ze sady series! v aktuální pozcici |
|
|
Interní |
Callback funkce musí vrátit hodnotu typu logic!
, jež indikuje, zda se má v parsování pokračovat (true
) či nikoli (false
).
Za účelem ladění je implicitně poskytnuto zpětné volání (callback) on-parse-event
a jeho parse-trace
wrapper.
V této části jsou stručně zmíněny některé údaje o návrhu a implementaci dialektu Parse.
Jak již bylo dříve zmíněno, Parse používá volné přirovnání (loose comparison) pro porovnávání literálových hodnot, což je konsistentní s Redem.
Příklad
parse [I'm 100% <sure>][quote :I'M 1.0 "sure"]
Do jisté míry podporuje Parse prostý (flat) formát, při němž jsou pravidla psána lineárně jako výrazy s proměnnou aritou, spíše než s pomocí vnořených bloků.
Příklad
parse [on the count of three 1 2 3][collect set stash keep pick to ahead some 1 3 integer! remove any skip]
Nevyřešené chyby a inkozistence návrhu, související s dialektem Parse jsou vypsány níže:
Affected rules | Description | Tickets |
---|---|---|
|
The case where position comes after the current one is not handled. |
|
|
Preemptive break of [Repetition] rules. |
|
|
Design of some [Control flow] rules is not finalized. |
|
|
Case-sensitive comparison is not handled properly. |
Kromě anglických i obecně cizích slov jsou v překladu použity jisté rádoby ekvivalentní výrazy, na něž chci zde upozornit:
-
series! - řada - vstup - vstupní objekt, náležející do typové sady series! případně název pravidla Parse
-
matched - konformní - shodující se s pravidlem
-
top-level-rule ? - řídící pravidlo