Navigation
Synopsis Parsing a Lisp expression.
Description Give the Lisp Syntax, we can now apply it to parse textual Lisp expressions and convert them to the runtime representation Lval.
module demo::lang::Lisra::Parse

import Prelude;
import demo::lang::Lisra::Syntax;
import demo::lang::Lisra::Runtime;

public Lval parse(str txt) = build(parse(#LispExp, txt));                          

// Build Abstract Synax Tree: Transform a LispExp to an Lval

public Lval build((LispExp)`<IntegerLiteral il>`) = Integer(toInt("<il>"));        
public Lval build((LispExp)`<AtomExp at>`)        = Atom("<at>");                  
public Lval build((LispExp)`( <LispExp* lst> )`)  = List([build(le) | le <- lst]); 

First we define the actual parse function (): it takes a string as argument and returns an Lval. It proceeds in two steps:
  • First the text is parsed using parse(#LispExp, txt). The result is parse tree.
  • Next, the auxiliary function build is used to transform the parse tree to an Lval.
Function build (--) is defined in cases, for the various parse tree forms. Fortunately, we do not have to spell out the details of the parse tree, but we can use concrete patterns instead. For instance, the argument pattern
(LispExp)`<IntegerLiteral il>`
says:
  • Match something of type LispExp.
  • It should be an IntegerLiteral and bind it to a variable il.
More precisely, the text between backquotes should be a string that can be parsed according to the non-terminal that precedes it (LispExp in this example). This is illustrated by the list case where the parentheses appear in the concrete pattern:
(LispExp)`( <LispExp* lst> )`
The right-hand sides of (--) deserve some attention:
  • In the argument il is a parse tree (!!) that represents an integer literal. We first convert it to a string using string interpolation ("<il>") and then convert it to an integer.
  • In the text of the atom is reconstructed in a similar fashion.
  • In the concrete list elements in lst are converted one-by-one using build and are then used to create a new List value.
Examples
rascal>import demo::lang::Lisra::Parse;
ok
rascal>import demo::lang::Lisra::Runtime;
ok
rascal>parse("1");
Lval: Integer(1)
rascal>parse("x");
Lval: Atom("x")
rascal>parse("(+ 5 7)");
Lval: List([
    Atom("+"),
    Integer(5),
    Integer(7)
  ])
Is this page unclear, or have you spotted an error? Please add a comment below and help us to improve it. For all other questions and remarks, visit ask.rascal-mpl.org.