summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cook/debug.sld29
-rw-r--r--cook/parse-internals.sld50
-rw-r--r--cook/parse.scm28
-rw-r--r--cook/parse.sld20
-rw-r--r--tests/parse.scm44
5 files changed, 154 insertions, 17 deletions
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"))