<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<HTML>
  <HEAD>
    <link rel="icon"          href="/favicon.ico" type="image/x-icon">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="stylesheet"    href="../../../../../../default.css"  type="text/css">

    <TITLE>A Parser for M-Expressions</TITLE>

    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    <META HTTP-EQUIV="Description"
          NAME="description" CONTENT="M-Expressions, The Original LISP">
    <META NAME="author"      CONTENT="Pascal J. Bourguignon">
    <META NAME="keywords"    CONTENT="LISP, Common Lisp, M-Expressions">
  </HEAD>
  <BODY>
    <!--TOP-BEGIN-->
    <!--TOP-END-->
    <!--MENU-BEGIN-->
    <!--MENU-END-->

    <h1>A Parser for M-Expressions</h1>
    <p>Here is a parser for Lisp M-Expressions as documented in the
      <a href="../aim-8/index.html">Memo 8, AIM-8</a></p>

    <p>
      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.
    </p>
    <p>
      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 <tt>lambda[[...];...]</tt>.
      Macros were added later in lisp history.
    </p>
    <p>
      Note that S-expressions can still be entered, as literal objects,
      but using comma instead of space to separate the items in lists.
    </p>
    <p>The file <A HREF="m-expression.lisp">m-expression.lisp</A>
      contains the M-expression parser and a REPL, in Common-Lisp.</p>

    <h2>Exemple</h2>

<pre>
% <b>/usr/local/bin/clisp -q -norc -ansi </b>

[1]&gt; <b>(load"m-expression.lisp" :external-format #+clisp charset:utf-8 #+sbcl :utf-8)</b>
;; Loading file m-expression.lisp ...
;; Loaded file m-expression.lisp
T
[2]&gt; <b>(m-repl)</b>

;; 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&gt; <b>shadow[SUBST];</b>
 --&gt; T

COMMON-LISP-USER[2]M-REPL&gt; <b>label[subst;λ[[x;y;s];[null[s]-&gt;nil;atom[s]⟶
           [y=s-&gt;x;1-&gt;s];1-&gt;combine[subst[x;y;first[s]];
                subst[x;y;rest[s]]]]]];</b>
 --&gt; SUBST

;; S-expressions embedded in M-expressions must use comma as separator:
COMMON-LISP-USER[3]M-REPL&gt; <b>subst[WATER;WINE;(MIX WATER AND WINE
                                  INTO (MIXED WATER AND WINE))];</b>
SIMPLE-ERROR:
Unexpected S-CLOSE, not (:S-SYMBOL WATER)
 at " AND WINE"

COMMON-LISP-USER[4]M-REPL&gt; SIMPLE-ERROR:
Please terminate your m-expressions with a semi-colon, not (:S-OPEN)

COMMON-LISP-USER[5]M-REPL&gt;
SIMPLE-ERROR:
Please terminate your m-expressions with a semi-colon, not (:S-SYMBOL WATER)

COMMON-LISP-USER[6]M-REPL&gt;
SIMPLE-ERROR:
Please terminate your m-expressions with a semi-colon, not (:S-SYMBOL WINE)

COMMON-LISP-USER[7]M-REPL&gt;
SIMPLE-ERROR:
Unexpected token in m-term: (:S-CLOSE)
 at ")];"

COMMON-LISP-USER[8]M-REPL&gt; <b>subst[WATER;WINE;(MIX,WATER,AND,WINE,
                                 INTO,(MIXED,WATER,AND,WINE))];</b>
 --&gt; (MIX WATER AND WATER INTO (MIXED WATER AND WATER))

COMMON-LISP-USER[9]M-REPL&gt; <b>subst[WINE;WATER;(MIX,WATER,AND,WINE,
                                 INTO,(MIXED,WATER,AND,WINE))];</b>
 --&gt; (MIX WINE AND WINE INTO (MIXED WINE AND WINE))

COMMON-LISP-USER[10]M-REPL&gt; <b>first[((A,B),C,D)]=(A,B);</b>

 --&gt; NIL

COMMON-LISP-USER[11]M-REPL&gt; <b>combine[A;⋀];</b>
 --&gt; (A)

COMMON-LISP-USER[12]M-REPL&gt; <b>quit[];</b>
NIL
[3]&gt;

  </pre>


<!--MENU-BEGIN-->
<!--MENU-END-->
<!--BOTTOM-BEGIN-->
<!--BOTTOM-END-->
 </BODY>
</HTML>
ViewGit