Skip to content

Instantly share code, notes, and snippets.

@pstuifzand
Last active March 20, 2016 06:36
Show Gist options
  • Save pstuifzand/5930450 to your computer and use it in GitHub Desktop.
Save pstuifzand/5930450 to your computer and use it in GitHub Desktop.
Simple Lisp parser for Marpa
use lib 'lib';
use Stuifzand::Lisp;
use Data::Dumper;
my $p = Stuifzand::Lisp->new;
my $r = $p->parse(<<'LISP');
(define eval (lambda (exp env)
(cond
((symbol? exp) (cdr (assoc exp env)))
((atom? exp) exp)
('t
(let ((fn (eval (car exp) env)))
(if (fixed? fn)
(apply (<fixed>-function fn) (cdr exp) env)
(apply fn (evlis (cdr exp) env) env)))))))
LISP
print Dumper($r);
package Stuifzand::Lisp;
use Marpa::R2;
sub new {
my ($class) = @_;
my $self = bless {}, $class;
$self->{grammar} = Marpa::R2::Scanless::G->new(
{
action_object => 'Stuifzand::Lisp::Actions',
default_action => '::first',
source => \(<<'END_OF_SOURCE'),
:start ::= lisp
lisp ::= exprs
expr ::= number
| string action => string
| id
| list
| ['] expr
| '`' expr
| ',' expr
list ::= ('(') members (')')
members ::= exprs
| expr ('.') expr action => ::array
exprs ::= expr action => ::array
exprs ::= expr exprs action => ::array
exprs ::= action => ::undef
id ~ [\w\-=*+/<>#%^&@?]+
number ~ [\d]+
string ~ '"' in_string '"'
in_string ~ in_string_char*
in_string_char ~ [^"\\]
| '\"'
| '\u' four_hex_digits
| '\\'
four_hex_digits ~ hex_digit hex_digit hex_digit hex_digit
hex_digit ~ [0-9a-fA-F]
:discard ~ ws
ws ~ [\s]+
END_OF_SOURCE
}
);
return $self;
}
sub parse {
my ($self, $string) = @_;
my $re = Marpa::R2::Scanless::R->new( { grammar => $self->{grammar} } );
$re->read(\$string);
my $value_ref = $re->value();
return ${$value_ref};
}
sub parse_sexp {
my ($string) = @_;
my $parser = MarpaX::Makefile->new();
return $parser->parse($string);
}
package Stuifzand::Lisp::Actions;
use strict;
use Data::Dumper;
sub new {
my ($class) = @_;
return bless {}, $class;
}
sub string {
my ($self, $string) = @_;
$string =~ s/^"//;
$string =~ s/"$//;
return $string;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment