#lang pl #| "{{{2 + 5}} * {5 * {{3 + 6}}}}" The parenthesis ^here & ^here are necessary because otherwise it would be an AE, not a Prod as R3 requires. It requires this to maintain order of operations. "{{{2 + 5}} * {5 * {{3 * 6}}}}" The parenthesis are no longer needed, as {3 * 6} is itself a prod satisfying R3. If you have a grammar language with easy precedence, it's nice. Otherwise, it's cursed. In Yacc: %left ADD SUB %left MUL DIV %precedence NEG exp: ... | NUM {...} | GROUPSTART exp GROUPEND { ... } | SUB exp {...} | exp SUM exp {...} | exp SUB exp {...} | exp MUL exp {...} | exp DIV exp {...} |# (define-type AE [R1 Prod AE] [R2 Prod]) (define-type Prod [R3 Atom Prod] [R4 Atom]) (define-type Atom [R5 Number] [R6 AE]) #| ::= + (1) | (2) ::= * (3) | (4) ::= (5) | { } (6) |# ; Symbols: ; 'sum ; 'mul ; 'groups ; 'groupe (: parseae : (Sexpr -> AE)) (define (parseae s) (match s [(list prod '+ ae) (R1 (parseprod prod) (parseae ae))] [prod (R2 (parseprod prod))])) (: parseprod : (Sexpr -> Prod)) (define (parseprod s) (match s [(list atom '* prod) (R3 (parseatom atom) (parseprod prod))] [ atom (R4 (parseatom atom))])) (: parseatom : (Sexpr -> Atom)) (define (parseatom s) (match s [ (number: n) (R5 n)] [(list ae) (R6 (parseae ae))])) (: parse : (String -> AE)) (define (parse s) (parseae (string->sexpr s))) (test (parse "5") => (R2 (R4 (R5 5)))) (test (parse "{2 + 5}") => (R1 (R4 (R5 2)) (R2 (R4 (R5 5))))) (test (parse "{{{2 + 5}} * {5 * {{3 + 6}}}}") => (R2 (R3 (R6 (R1 (R4 (R5 2)) (R2 (R4 (R5 5))))) (R3 (R5 5) (R4 (R6 (R1 (R4 (R5 3)) (R2 (R4 (R5 6))))))))) ) ; parse-ae/h: s: Sexpr, ae: AE → AE #| ::= + (1) | (2) ::= * (3) | (4) ::= (5) | { } (6) These are not wrapped in the few rules at the top level to convert them to AEs "5" (5) 5 "{5}" (6) (2) (4) (5) 5 "{2 + 5}" (6) (1) (4) (5) 2 (2) (4) (5) 5 "{{{2 + 5}} * {5 * {{3 + 6}}}}" (6) (2) (3) (6) (6) (1) (4) (5) 2 (2) (4) (5) 5 (4) (6) (3) (5) 5 (4) (6) (6) (1) (4) (5) 3 (2) (4) (5) 6 |#