From 518fb8205ae251e10d642fc8816f0a6720e3b440 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Sat, 10 Aug 2024 16:04:45 +0200 Subject: Make some project structure --- cook/debug.sld | 29 ++++++++++++++++++++++++++++ cook/parse-internals.sld | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ cook/parse.scm | 28 +++++++++++++-------------- cook/parse.sld | 20 +++++++++++++++++-- tests/parse.scm | 44 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 cook/debug.sld create mode 100644 cook/parse-internals.sld create mode 100644 tests/parse.scm diff --git a/cook/debug.sld b/cook/debug.sld new file mode 100644 index 0000000..9ae9638 --- /dev/null +++ b/cook/debug.sld @@ -0,0 +1,29 @@ +(define-library (cook debug) + (export cook->list) + (import (srfi 1) + (srfi 9) + (srfi 69) + (chibi) + (cook parse-internals)) + (begin + (define (cook->list y) + (cond + ((amount? y) + (list 'amount (amount-quantity y) (amount-unit y))) + ((component? y) + (list 'component (component-name y) (cook->list (component-amount y)))) + ((cookware? y) + (list 'cookware (cookware-name y) (cook->list (cookware-amount y)))) + ((ingredient? y) + (list 'ingredient (ingredient-name y) (cook->list (ingredient-amount y)))) + ((timer? y) + (list 'timer (timer-name y) (cook->list (timer-amount y)))) + ((metadata-line? y) + (list 'metadata-line (metadata-line-key y) (metadata-line-value y))) + ((step? y) + (list 'step (map cook->list (step-elements y)))) + ((hash-table? y) + (list 'metadata (cook->list (hash-table->alist y)))) + ((list? y) + (map cook->list y)) + (else y))))) diff --git a/cook/parse-internals.sld b/cook/parse-internals.sld new file mode 100644 index 0000000..5b8df2e --- /dev/null +++ b/cook/parse-internals.sld @@ -0,0 +1,50 @@ +(define-library (cook parse-internals) + (import (srfi 1) + (srfi 9) + (srfi 69) + (chibi) + (chibi char-set ascii) + (chibi char-set) + (chibi parse) + (chibi regexp) + (chibi parse common)) + (export amount? + amount-quantity + amount-unit + ingredient? + ingredient-name + ingredient-amount + timer? + timer-name + timer-amount + component? + component-name + component-amount + cookware? + cookware-name + cookware-amount + metadata-line? + metadata-line-key + metadata-line-value + step? + step-elements + parse-cook + nl + whitespace + any-text-item + text-item + comment + word + unit + quantity + amount + meta-key + no-word-component + component + timer + cookware + ingredient + step + metadata + recipe) + (include "parse.scm")) diff --git a/cook/parse.scm b/cook/parse.scm index 8403221..33bf3b0 100644 --- a/cook/parse.scm +++ b/cook/parse.scm @@ -1,11 +1,3 @@ -(import (srfi 1) - (srfi 9) - (srfi 69) - (chibi char-set ascii) - (chibi char-set) - (chibi parse) - (chibi regexp) - (chibi parse common)) #| https://github.com/cooklang/spec/blob/main/EBNF.md |# @@ -69,27 +61,31 @@ https://github.com/cooklang/spec/blob/main/EBNF.md metadata)) + (define newline-chars (char-set #\x000A #\x000D #\x0085 #\x2028 #\x2029)) (define punctuation-chars (char-set #\. #\{ #\})) ;; TODO: do it right (define word-chars (char-set-difference char-set:full punctuation-chars char-set:whitespace)) -(define text-chars (char-set-difference char-set:full - (char-set #\@ #\# #\~) +(define any-text-chars (char-set-difference char-set:full newline-chars)) +(define text-chars (char-set-difference any-text-chars + (char-set #\@ #\# #\~))) (define unit-chars (char-set-difference text-chars (char-set #\}))) (define component-chars (char-set-difference text-chars (char-set #\{ #\}))) (define quantity-chars (char-set-difference text-chars (char-set #\} #\%))) (define metadata-chars (char-set-difference text-chars (char-set #\:))) (define-grammar cook - (newline ((+ ,newline-chars))) + (nl ((+ ,newline-chars))) (whitespace ((+ ,char-set:whitespace))) + (any-text-item ((: (=> c (+ ,any-text-chars))) + (list->string c))) (text-item ((: (=> c (+ ,text-chars))) (list->string c))) - (comment ((: "--" (=> c (+ ,text-chars)) ,newline) + (comment ((: "--" (=> c (+ ,any-text-chars)) ,nl) (list->string c)) ((: "[-" (=> c (* any)) "-]") (list->string c))) @@ -127,16 +123,18 @@ https://github.com/cooklang/spec/blob/main/EBNF.md ,cookware ,timer ,text-item))) - ,newline) + ,nl) (make-step s))) (metadata ((: bol ">>" (* ,whitespace) (=> k ,meta-key) (* ,whitespace) ":" (* ,whitespace) - (=> v ,text-item) (* ,whitespace) ,newline) + (=> v ,any-text-item) (* ,whitespace) ,nl) (make-metadata-line k v))) - (recipe ((* (or (=> m (+ ,metadata)) (=> s (+ ,step)))) + (recipe ((* (or (=> m (+ ,metadata)) + (=> c (+ ,comment))) + (=> s (+ ,step))) (list 'recipe (metadata-line-list->hash-table m) s)))) (define (parse-cook str) diff --git a/cook/parse.sld b/cook/parse.sld index 9f4eaa3..29742b0 100644 --- a/cook/parse.sld +++ b/cook/parse.sld @@ -1,10 +1,26 @@ (define-library (cook parse) - (export parse-cook) (import (srfi 1) (srfi 9) (srfi 69) + (chibi) (chibi char-set ascii) (chibi char-set) (chibi parse) - (chibi regexp)) + (chibi regexp) + (chibi parse common)) + (export amount? + amount-quantity + amount-unit + ingredient? + ingredient-name + ingredient-amount + timer? + timer-name + timer-amount + cookware? + cookware-name + cookware-amount + step? + step-elements + parse-cook) (include "parse.scm")) diff --git a/tests/parse.scm b/tests/parse.scm new file mode 100644 index 0000000..c4670e0 --- /dev/null +++ b/tests/parse.scm @@ -0,0 +1,44 @@ +(import (chibi) + (chibi test) + (chibi parse) + (cook debug) + (cook parse-internals)) + +(test "Amount with unit" + (list 'amount "10" "l") (cook->list (parse amount "10%l"))) +(test "Amount without unit" + (list 'amount "10" #f) (cook->list (parse amount "10"))) + +;(define (test x y) +; (display "Testing: ") +; (display x) +; (display " == ") +; (display (cook->list y)) +; (newline)) + +;(test 'NEWLINE (parse nl "\n\r\r\n")) +;(test 'WHITESPACE (parse whitespace " \t aaaa aaa ")) +;(test 'COMMENT (parse comment "-- aasf ljalsfkjalsfdjalsfd\n")) +; +;(test 'BLOCK-COMMENT ;; TODO: Check greediness +; (parse comment "[- aasfjal sfkjalsfdjalsfd\nashfajsdf\nsdfasf-]")) +; +;(test 'WORD (parse word "hola. adios")) +;(test 'UNIT (parse unit "l")) +;(test 'QUANTITY (parse quantity "10")) +;(test 'WORD-COMPONENT (parse-fully component "word{}")) +;(test 'WORD-COMPONENT (parse-fully component "word{9%head}")) +;(test 'WORD-COMPONENT (parse-fully component "word")) +;(test 'MULTI-WORD-COMPONENT (parse-fully component "un multi word{}")) +;(test 'MULTI-WORD-COMPONENT (parse-fully component "un multi word{10}")) +;(test 'MULTI-WORD-COMPONENT (parse-fully component "un multi word{10%l}")) +;(test 'MULTI-WORD-COMPONENT (parse-fully component "un multi word{80%mm}")) +;(test 'NO-NAME-TIMER (parse-fully timer "~{}")) +;(test 'MULTI-WORD-TIMER (parse-fully timer "~un multi word{10}")) +;(test 'MULTI-WORD-TIMER (parse-fully timer "~un multi word{10%l}")) +;(test 'MULTI-WORD-TIMER (parse-fully timer "~un multi word{80%mm}")) +;(test 'NO-NAME-TIMER (parse-fully timer "~{12%min}")) +;(test 'INGREDIENT (parse-fully ingredient "@potato{12%kg}")) +;(test 'STEP (parse-fully step "un poco de texto seguido de ~un multi word{10}")) +;(test 'RECIPE (parse recipe "this is a recipe with @coconut{1}\nAnd takes ~{2%min}\n")) +;(test 'RECIPE (parse recipe ">> some: metadata\nthis is a recipe with @coconut{1}\nAnd takes ~{2%min}\n")) -- cgit v1.2.3