Here is a parser for Lisp M-Expressions as documented in the Memo 8, AIM-8
A lot of lisp newbies ask for more conventionnal syntax for lisp. Since day one, lisp was intended to have such a syntax: M-expressions.
Let's newbies play with them, and realize how impractical they are. Note for example, that we cannot use macros anymore because their syntax would need to be known by the M-expression parser, like it's the case for lambda[[...];...]. Macros were added later in lisp history.
Note that S-expressions can still be entered, as literal objects, but using comma instead of space to separate the items in lists.
The file m-expression.lisp contains the M-expression parser and a REPL, in Common-Lisp.
% /usr/local/bin/clisp -q -norc -ansi [1]> (load"m-expression.lisp" :external-format #+clisp charset:utf-8 #+sbcl :utf-8) ;; Loading file m-expression.lisp ... ;; Loaded file m-expression.lisp T [2]> (m-repl) ;; We are going to define a function that is exported by COMMON-LISP, ;; so let's shadow it first: COMMON-LISP-USER[1]M-REPL> shadow[SUBST]; --> T COMMON-LISP-USER[2]M-REPL> label[subst;λ[[x;y;s];[null[s]->nil;atom[s]⟶ [y=s->x;1->s];1->combine[subst[x;y;first[s]]; subst[x;y;rest[s]]]]]]; --> SUBST ;; S-expressions embedded in M-expressions must use comma as separator: COMMON-LISP-USER[3]M-REPL> subst[WATER;WINE;(MIX WATER AND WINE INTO (MIXED WATER AND WINE))]; SIMPLE-ERROR: Unexpected S-CLOSE, not (:S-SYMBOL WATER) at " AND WINE" COMMON-LISP-USER[4]M-REPL> SIMPLE-ERROR: Please terminate your m-expressions with a semi-colon, not (:S-OPEN) COMMON-LISP-USER[5]M-REPL> SIMPLE-ERROR: Please terminate your m-expressions with a semi-colon, not (:S-SYMBOL WATER) COMMON-LISP-USER[6]M-REPL> SIMPLE-ERROR: Please terminate your m-expressions with a semi-colon, not (:S-SYMBOL WINE) COMMON-LISP-USER[7]M-REPL> SIMPLE-ERROR: Unexpected token in m-term: (:S-CLOSE) at ")];" COMMON-LISP-USER[8]M-REPL> subst[WATER;WINE;(MIX,WATER,AND,WINE, INTO,(MIXED,WATER,AND,WINE))]; --> (MIX WATER AND WATER INTO (MIXED WATER AND WATER)) COMMON-LISP-USER[9]M-REPL> subst[WINE;WATER;(MIX,WATER,AND,WINE, INTO,(MIXED,WATER,AND,WINE))]; --> (MIX WINE AND WINE INTO (MIXED WINE AND WINE)) COMMON-LISP-USER[10]M-REPL> first[((A,B),C,D)]=(A,B); --> NIL COMMON-LISP-USER[11]M-REPL> combine[A;⋀]; --> (A) COMMON-LISP-USER[12]M-REPL> quit[]; NIL [3]>