The problem: A full parser plus lexer consists of of a set of three different things: . Grammar rules for the LALR(1) parser . Regex macros (like 'digit') . Tokens Later maybe even: . Macros for the grammar section How to tell these apart? ------------------------------------------------------------------------------- variant i -- magic ( sum -> product -> product "+" sum => (+ $1 $3)) (product -> factor -> factor "*" factor => (* $1 $3)) ( factor -> :number -> "(" sum ")" => $2) (:number -> (+ digit) => (parse-integer $$)) ( digit -> (range #\0 #\9)) (:ignore -> #\space) ------------------------------------------------------------------------------- variant ii -- special 'token' rule and some magic ( sum -> product -> product "+" sum => (+ $1 $3)) (product -> factor -> factor "*" factor => (* $1 $3)) ( factor -> number -> "(" sum ")" => $2) (token -> number -> space) (number -> (+ digit) => (parse-integer $$)) ( digit -> (range #\0 #\9)) (space -> #\space) ------------------------------------------------------------------------------- variant iii -- separate sections :rules ( sum -> product -> product "+" sum => (+ $1 $3)) (product -> factor -> factor "*" factor => (* $1 $3)) ( factor -> :number -> "(" sum ")" => $2) :defs ( digit -> (range #\0 #\9)) :tokens (:number -> (+ digit) => (parse-integer $$)) (:ignore -> #\space) ------------------------------------------------------------------------------- variant iv -- each 'rule' prefixed (:rule sum -> product -> product "+" sum => (+ $1 $3)) (:rule product -> factor -> factor "*" factor => (* $1 $3)) (:rule factor -> number -> "(" sum ")" => $2) (:macro digit -> (range #\0 #\9)) (:token number -> (+ digit) => (parse-integer $$)) (:token ignore -> #\space) ------------------------------------------------------------------------------- variant v -- each 'rule' infixed ( sum --> product --> product "+" sum => (+ $1 $3)) (roduct --> factor --> factor "*" factor => (* $1 $3)) (factor --> number --> "(" sum ")" => $2) ( digit = (range #\0 #\9)) (number -> (+ digit) => (parse-integer $$)) (ignore -> #\space)