I am looking at the Exp example in the Tutorial.
Is it possible to control layout conditionally? Consider, for example, Python expressions:
For example: (1 + \n 3)
is a valid expression, but 1 +\n 3
is not.
If not, what would be the easiest way of achieving the same result, short of sprinkling newlines through my grammar?
Yes it's possible:
layout
non-terminal L
in a syntax
rule between two normal symbols A
and B
like so: syntax NY = "foo" A L B "bar", then Rascal will not add more layout non-terminals between the A
and L
or between L
and B
layout NoNewLineLayout = @manual [\t\ ]*;
So this requires sprinkling instances of NoNewLineLayout symbols in your grammar, rather than sprinkling newlines. I normally use a short name like NNL to make this less intrusive. We used this workaround for experimenting with Javascript grammars and other layout sensitive languages. In general, though it is not perfect and we've been working more elegant solutions, see http://dl.acm.org/citation.cfm?id=2814242 for a preview.
A second less flexible solution is to use the scope of layout
definitions (which is module scoped). The layout definition in the current module takes precedence over any imported layout definitions. In such a way one can influence which layout non-terminal is woven in which rules. This comes mostly in handy when embedding languages into other languages which may have different comment conventions and such; for the current use case, I wouldn't advise it.