Wouter Nederhof
Wouter Nederhof

Reputation: 79

Layout in Rascal

When I import the Lisra recipe,

import demo::lang::Lisra::Syntax;

This creates the syntax:

layout Whitespace      = [\t-\n\r\ ]*; 
lexical IntegerLiteral = [0-9]+ !>> [0-9];
lexical AtomExp        = (![0-9()\t-\n\r\ ])+ !>>  ![0-9()\t-\n\r\ ];

start syntax LispExp
      = IntegerLiteral
      | AtomExp
      | "(" LispExp* ")"
      ;

Through the start syntax-definition, layout should be ignored around the input when it is parsed, as is stated in the documentation: http://tutor.rascal-mpl.org/Rascal/Declarations/SyntaxDefinition/SyntaxDefinition.html

However, when I type:

rascal>(LispExp)` (something)`

This gives me a concrete syntax fragment error (or a ParseError when using the parse-function), in contrast to:

rascal>(LispExp)`(something)`

Which succesfully parses. I tried this both with one of the latest versions of Rascal as well as the Eclipse plugin version. Am I doing something wrong here?

Thank you.

Ps. Lisra's parse-function:

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

Also fails on the example:

rascal>parse(" (something)")
|project://rascal/src/org/rascalmpl/library/ParseTree.rsc|(10329,833,<253,0>,<279,60>): ParseError(|unknown:///|(0,1,<1,0>,<1,1>))
    at *** somewhere ***(|project://rascal/src/org/rascalmpl/library/ParseTree.rsc|(10329,833,<253,0>,<279,60>))
    at parse(|project://rascal/src/org/rascalmpl/library/demo/lang/Lisra/Parse.rsc|(163,3,<7,44>,<7,47>))
    at $shell$(|stdin:///|(0,13,<1,0>,<1,13>))

Upvotes: 1

Views: 339

Answers (1)

Jurgen Vinju
Jurgen Vinju

Reputation: 6696

When you define a start non-terminal Rascal defines two non-terminals in one go:

rascal>start syntax A = "a";
ok

One non-terminal is A, the other is start[A]. Given a layout non-terminal in scope, say L, the latter is automatically defined by (something like) this rule:

syntax start[A] = L before A top L after;

If you call a parser or wish to parse a concrete fragment, you can use either non-terminal:

parse(#start[A], " a ") // parse using the start non-terminal and extra layout
parse(A, "a") // parse only an A
(start[A]) ` a ` // concrete fragment for the start-non-terminal
(A) `a` // concrete fragment for only an A
[start[A]] " a "
[A] "a"

Upvotes: 1

Related Questions