Skip to content

Instantly share code, notes, and snippets.

@jurgenvinju
Created October 4, 2012 13:46
Show Gist options
  • Save jurgenvinju/3833624 to your computer and use it in GitHub Desktop.
Save jurgenvinju/3833624 to your computer and use it in GitHub Desktop.
A working experiment (co-authored with @seba--) on implementing his disambiguation declarations for layout-sensitive languages in Rascal
@doc{an alternative to Offside.rsc which directly uses * lists instead of manual recursion}
module ListOffside
import IO;
start syntax Program = program: Def*;
lexical Id = [a-z]+;
syntax Def
= assign: Id id "=" Exp exp
| left when: Def "when" Def
;
syntax Exp
= id: Id
| left add: Exp "+" Exp
;
layout WS = [\ \t\n]*;
alias Pos = tuple[int line, int col];
public Program program((Def*) `<Def* _> <Def d1> <Def d2> <Def* _>`) {
if (first(d1).col != first(d2).col) {
println("<d2> is not aligned at <first(d2).line>");
filter;
}
fail;
}
public Def assign(Def def) {
l = left(def);
if (l.col == -1 || first(def).col < l.col)
return def;
println("it\'s offside :-( <l>, def: <def>, fundebug: <first(def)>");
filter;
}
public Pos first(Tree x) = (x@\loc).begin ? <-1,-1>;
public Pos left(Tree x) {
Pos current = <-1,-1>;
firstLine = first(x).line;
// skip layout
// skip ignore
visit(x) {
case Tree child: {
pos = first(child);
if (pos != <-1,-1>, pos.line > firstLine) {
if (current.col == -1 || current.col > pos.col) {
current = pos;
}
}
}
}
return current;
}
module Offside
import IO;
start syntax Program = program: Defs;
syntax Defs = right defs: Defs lhs Defs rhs | def: Def;
lexical Id = [a-z]+;
syntax Def
= assign: Id id "=" Exp exp
| left when: Def "when" Def
;
syntax Exp
= id: Id
| left add: Exp "+" Exp
;
layout WS = [\ \t\n]*;
alias Pos = tuple[int line, int col];
public Defs defs(Defs defs) {
lhs = defs.lhs;
rhs = defs.rhs;
if (first(lhs).col == first(rhs).col)
return defs;
println("it\'s not aligned! <lhs> with <rhs>");
filter;
}
public Def assign(Def def) {
l = left(def);
if (l.col == -1 || first(def).col < l.col)
return def;
println("it\'s offside :-( <l>, def: <def>, fundebug: <first(def)>");
filter;
}
public Pos first(Tree x) = (x@\loc).begin ? <-1,-1>;
public Pos left(Tree x) {
Pos current = <-1,-1>;
firstLine = first(x).line;
// skip layout
// skip ignore
visit(x) {
case Tree child: {
pos = first(child);
if (pos != <-1,-1>, pos.line > firstLine) {
if (current.col == -1 || current.col > pos.col) {
current = pos;
}
}
}
}
return current;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment