Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 29 additions & 32 deletions src/org/rascalmpl/library/ParseTree.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ A `Tree` defines the trees normally found after parsing; additional constructors
<4> A single character.
}

data Tree //(loc src = |unknown:///|(0,0,<0,0>,<0,0>))
data Tree(loc src = |unknown:///|(0,0,<0,0>,<0,0>))
= appl(Production prod, list[Tree] args) // <1>
| cycle(Symbol symbol, int cycleLength) // <2>
| amb(set[Tree] alternatives) // <3>
Expand Down Expand Up @@ -328,11 +328,6 @@ Production associativity(Symbol rhs, Associativity a, {associativity(rhs, Associ
Production associativity(Symbol s, Associativity as, {*Production a, priority(Symbol t, list[Production] b)})
= associativity(s, as, {*a, *b});


@synopsis{Annotate a parse tree node with a source location.}
anno loc Tree@\loc;


@synopsis{Parse input text (from a string or a location) and return a parse tree.}
@description{
* Parse a string and return a parse tree.
Expand Down Expand Up @@ -692,48 +687,51 @@ data Exp = add(Exp, Exp);
java &T<:value implode(type[&T<:value] t, Tree tree);


@synopsis{Annotate a parse tree node with an (error) message.}
anno Message Tree@message;

@synopsis{A bottom value for Message is interpreted as no message at all.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Message = silence();

@synopsis{Annotate a parse tree node with a list of (error) messages.}
anno set[Message] Tree@messages;
@synopsis{Annotate a parse tree node with an (error) message.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(Message message = silence());

@synopsis{Annotate a parse tree node with a list of (error) messages.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(set[Message] messages = {});

@synopsis{Annotate a parse tree node with a documentation string.}
anno str Tree@doc;

@synopsis{Annotate a parse tree node with a documentation string.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(str doc = "");

@synopsis{Annotate a parse tree node with documentation strings for several locations.}
anno map[loc,str] Tree@docs;

@synopsis{Annotate a parse tree node with documentation strings for several locations.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(map[loc,str] docs = ());

@synopsis{Annotate a parse tree node with the target of a reference.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(loc link = |unknown:///|);

@synopsis{Annotate a parse tree node with the target of a reference.}
anno loc Tree@link;

@synopsis{Annotate a parse tree node with multiple targets for a reference.}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(set[loc] links = {});

@synopsis{Annotate a parse tree node with multiple targets for a reference.}
anno set[loc] Tree@links;


@synopsis{Annotate the top of the tree with hyperlinks between entities in the tree (or other trees)

This is similar to link and links annotations, except that you can put it as one set at the top of the tree.}
anno rel[loc,loc] Tree@hyperlinks;

@synopsis{Annotate the top of the tree with hyperlinks between entities in the tree (or other trees)}
@description{
This is similar to link and links annotations, except that you can put it as one set at the top of the tree.
}
@deprecated{Use util::LanguageServer and util::IDEServices instead. This only works in Eclipse.}
data Tree(rel[loc,loc] hyperlinks = {});

@synopsis{Tree search result type for ((treeAt)).}
data TreeSearchResult[&T<:Tree] = treeFound(&T tree) | treeNotFound();



@synopsis{Select the innermost Tree of a given type which is enclosed by a given location.}
@description{

}
TreeSearchResult[&T<:Tree] treeAt(type[&T<:Tree] t, loc l, Tree a:appl(_, _)) {
if ((a@\loc)?, al := a@\loc, al.offset <= l.offset, al.offset + al.length >= l.offset + l.length) {
if ((a.src)?, al := a.src, al.offset <= l.offset, al.offset + al.length >= l.offset + l.length) {
for (arg <- a.args, TreeSearchResult[&T<:Tree] r:treeFound(&T<:Tree _) := treeAt(t, l, arg)) {
return r;
}
Expand All @@ -754,7 +752,6 @@ bool sameType(conditional(Symbol s,_), Symbol t) = sameType(s,t);
bool sameType(Symbol s, s) = true;
default bool sameType(Symbol s, Symbol t) = false;


@synopsis{Determine if the given type is a non-terminal type.}
bool isNonTerminalType(Symbol::\sort(str _)) = true;
bool isNonTerminalType(Symbol::\lex(str _)) = true;
Expand Down
78 changes: 39 additions & 39 deletions src/org/rascalmpl/library/analysis/grammars/Ambiguity.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public list[Message] diagnose(str amb) {
}

public list[Message] findCauses(Tree a) {
return [info("Ambiguity cluster with <size(a.alternatives)> alternatives", a@\loc?|dunno:///|)]
return [info("Ambiguity cluster with <size(a.alternatives)> alternatives", a.src)]
+ [*findCauses(x, y) | [*_,Tree x,*_,Tree y, *_] := toList(a.alternatives), true /* workaround alert*/];
}

Expand All @@ -36,22 +36,22 @@ public list[Message] findCauses(Tree x, Tree y) {
list[Message] result = [];

if (pX == pY) {
result += [info("The alternatives use the same productions", x@\loc?|dunno:///|)];
result += [info("The alternatives use the same productions", x.src)];
}
else {
result += [info("Production unique to the one alternative: <alt2rascal(p)>;", x@\loc?|dunno:///|) | p <- pX - pY];
result += [info("Production unique to the other alternative: <alt2rascal(p)>;", x@\loc?|dunno:///|) | p <- pY - pX];
result += [info("Production unique to the one alternative: <alt2rascal(p)>;", x.src) | p <- pX - pY];
result += [info("Production unique to the other alternative: <alt2rascal(p)>;", x.src) | p <- pY - pX];
}

if (appl(prodX,_) := x, appl(prodY,_) := y) {
if (prodX == prodY) {
result += [info("The alternatives have the same production at the top: <alt2rascal(prodX)>", x@\loc?|dunno:///|)];
result += [info("The alternatives have the same production at the top: <alt2rascal(prodX)>", x.src)];
}
else {
result += [info("The alternatives have different productions at the top, one has
' <alt2rascal(prodX)>
'while the other has
' <alt2rascal(prodY)>", x@\loc?|dunno:///|)];
' <alt2rascal(prodY)>", x.src)];
}
}

Expand All @@ -78,15 +78,15 @@ public list[Message] exceptAdvise(Tree x, set[Production] _, set[Production] pY)
}
else {
result += [warning("You should give this production a good label:
' <alt2rascal(apX)>]",x@\loc?|dunno:///|)];
' <alt2rascal(apX)>]",x.src)];
}

result += [error("To fix this issue, you could restrict the nesting of
' <alt2rascal(apX)>
'under
' <alt2rascal(p)>
'using the ! operator on argument <i/2>: !<labelApX>
'However, you should realize that you are introducing a restriction that makes the language smaller",x@\loc?|dunno:///|)];
'However, you should realize that you are introducing a restriction that makes the language smaller",x.src)];
}

}
Expand All @@ -108,22 +108,22 @@ public list[Message] deeperCauses(Tree x, Tree y, set[Production] pX, set[Produc
result = [];

if (rX<0> != rY<0> || lX<1> != lY<1>) {
result += [info("The alternatives have different lexicals/literals/layout", x@\loc?|dunno:///| )];
result += [info("Unique lexical to the one: <alt2rascal(p)>;", t[0]@\loc?|dunno:///|) | t <- (rX - rY), p := t[0].prod];
result += [info("Unique lexical to the other: <alt2rascal(p)>;", t[0]@\loc?|dunno:///|) | t <- (rY - rX), p := t[0].prod];
result += [info("Unique literal to the one: <symbol2rascal(t[1].prod.def)>", x@\loc?|dunno:///|) | t <- lX - lY];
result += [info("Unique literal to the other: <symbol2rascal(t[1].prod.def)>", x@\loc?|dunno:///|) | t <- lY - lX];
result += [info("Unique layout to the one: <symbol2rascal(t[0].prod.def)>", x@\loc?|dunno:///|) | t <- laX - laY];
result += [info("Unique layout to the other: <symbol2rascal(t[0].prod.def)>", x@\loc?|dunno:///|) | t <- laY - laX];
result += [info("The alternatives have different lexicals/literals/layout", x.src )];
result += [info("Unique lexical to the one: <alt2rascal(p)>;", t[0].src) | t <- (rX - rY), p := t[0].prod];
result += [info("Unique lexical to the other: <alt2rascal(p)>;", t[0].src) | t <- (rY - rX), p := t[0].prod];
result += [info("Unique literal to the one: <symbol2rascal(t[1].prod.def)>", x.src) | t <- lX - lY];
result += [info("Unique literal to the other: <symbol2rascal(t[1].prod.def)>", x.src) | t <- lY - lX];
result += [info("Unique layout to the one: <symbol2rascal(t[0].prod.def)>", x.src) | t <- laX - laY];
result += [info("Unique layout to the other: <symbol2rascal(t[0].prod.def)>", x.src) | t <- laY - laX];

// literals that became lexicals and vice versa
result += [error("You might reserve <l> from <symbol2rascal(r.prod.def)>, i.e. using a reject (reserved keyword).", r@\loc?|dunno:///|) | <r,l> <- rX o lY];
result += [error("You might reserve <l> from <symbol2rascal(r.prod.def)>, i.e. using a reject (reserved keyword).", r@\loc?|dunno:///|) | <r,l> <- rY o lX];
result += [error("You might reserve <l> from <symbol2rascal(r.prod.def)>, i.e. using a reject (reserved keyword).", r.src) | <r,l> <- rX o lY];
result += [error("You might reserve <l> from <symbol2rascal(r.prod.def)>, i.e. using a reject (reserved keyword).", r.src) | <r,l> <- rY o lX];

// lexicals that overlap position, but are shorter (longest match issue)
for (<tX,_> <- rX, <tY,_> <- rY, tX != tY) {
tXl = tX@\loc;
tYl = tY@\loc;
tXl = tX.src;
tYl = tY.src;

// <-------->
// <--->
Expand Down Expand Up @@ -153,14 +153,14 @@ public list[Message] deeperCauses(Tree x, Tree y, set[Production] pX, set[Produc


// find parents of literals, and transfer location
polX = {<p,l[@\loc=t@\loc?|dunno:///|]> | /t:appl(p,[*_,l:appl(prod(lit(_),_,_),_),*_]) := x, true};
polY = {<l[@\loc=t@\loc?|dunno:///|],p> | /t:appl(p,[*_,l:appl(prod(lit(_),_,_),_),*_]) := y, true};
polX = {<p,l[src=t.src]> | /t:appl(p,[*_,l:appl(prod(lit(_),_,_),_),*_]) := x, true};
polY = {<l[src=t.src],p> | /t:appl(p,[*_,l:appl(prod(lit(_),_,_),_),*_]) := y, true};
overloadedLits = [info("Literal \"<l>\" is used in both
' <alt2rascal(p)> and
' <alt2rascal(q)>", l@\loc) | <p,l> <- polX, <l,q> <- polY, p != q, !(p in pY || q in pX)];
' <alt2rascal(q)>", l.src) | <p,l> <- polX, <l,q> <- polY, p != q, !(p in pY || q in pX)];

if (overloadedLits != []) {
result += info("Re-use of these literals is causing different interpretations of the same source.", x@\loc?|dunno:///|);
result += info("Re-use of these literals is causing different interpretations of the same source.", x.src);
result += overloadedLits;

fatherChildX = {<p, size(a), q> | appl(p, [*a,appl(q,_),*_]) := x, q.def is sort || q.def is lex, true};
Expand All @@ -172,14 +172,14 @@ public list[Message] deeperCauses(Tree x, Tree y, set[Production] pX, set[Produc
labelApX = l;
}
else {
result += [warning("You should give this production a good label [<alt2rascal(q)>]",x@\loc?|dunno:///|)];
result += [warning("You should give this production a good label [<alt2rascal(q)>]",x.src)];
}

result += [error("You could safely restrict the nesting of
' <alt2rascal(q)>
'under
' <alt2rascal(p)>
'using the ! operator on argument <i/2>: !<labelApX>",x@\loc?|dunno:///|)];
'using the ! operator on argument <i/2>: !<labelApX>",x.src)];
}
}

Expand Down Expand Up @@ -210,16 +210,16 @@ public list[Message] reorderingCauses(Tree x, Tree y) {
list[Message] priorityCauses(Tree x, Tree y) {
if (/appl(p,[appl(q,_),*_]) := x, /Tree t:appl(q,[*_,appl(p,_)]) := y, p != q) {
return [error("You might add this priority rule (or vice versa):
' <alt2rascal(priority(p.def,[p,q]))>", t@\loc)
' <alt2rascal(priority(p.def,[p,q]))>", t.src)
,error("You might add this associativity rule (or right/assoc/non-assoc):
' <alt2rascal(associativity(p.def, \left(), {p,q}))>", t@\loc?|dunno:///|)];
' <alt2rascal(associativity(p.def, \left(), {p,q}))>", t.src)];
}

if (/appl(p,[appl(q,_),*_]) := y, /Tree t:appl(q,[*_,appl(p,_)]) := x, p != q) {
return [error("You might add this priority rule (or vice versa):
' <alt2rascal(priority(p.def,[p,q]))>", t@\loc)
' <alt2rascal(priority(p.def,[p,q]))>", t.src)
,error("You might add this associativity rule (or right/assoc/non-assoc):
' <alt2rascal(associativity(p.def, \left(), {p,q}))>", t@\loc?|dunno:///|)];
' <alt2rascal(associativity(p.def, \left(), {p,q}))>", t.src)];
}

return [];
Expand All @@ -237,40 +237,40 @@ list[Message] danglingCauses(Tree x, Tree y) {
list[Message] danglingFollowSolutions(Tree x, Tree y) {
if (prod(_, lhs, _) := x.prod, prod(_, [*pref, _, l:lit(_), *_], _) := y.prod, lhs == pref) {
return [error("You might add a follow restriction for <symbol2rascal(l)> on:
' <alt2rascal(x.prod)>", x@\loc?|dunno:///|)];
' <alt2rascal(x.prod)>", x.src)];
}

if (prod(_, lhs, _) := y.prod, prod(_, [*pref, _, l:lit(_), *_], _) := x.prod, lhs == pref) {
return [error("You might add a follow restriction for <symbol2rascal(l)> on:
' <alt2rascal(y.prod)>", x@\loc?|dunno:///|)];
' <alt2rascal(y.prod)>", x.src)];
}

return [];
}

list[Message] danglingOffsideSolutions(Tree x, Tree y) {
if (appl(p,/Tree u:appl(q,_)) := x, appl(q,/appl(p,_)) := y
, (u@\loc).begin.column >= (x@\loc).begin.column
, (u@\loc).begin.line < (x@\loc).end.line) {
return [error("You might declare nested <prod2rascal(q)> offside (to the left) of some child of <prod2rascal(p)> using a failing syntax action that compares annotations @loc.start.column", u@\loc)];
, (u.src).begin.column >= (x.src).begin.column
, (u.src).begin.line < (x.src).end.line) {
return [error("You might declare nested <prod2rascal(q)> offside (to the left) of some child of <prod2rascal(p)> using a failing syntax action that compares annotations @loc.start.column", u.src)];
}

if (appl(p,/Tree u:appl(q,_)) := y, appl(q,/appl(p,_)) := x
, (u@\loc).begin.column >= (y@\loc).begin.column
, (u@\loc).begin.line < (y@\loc).end.line) {
return [error("You might declare nested <prod2rascal(q)> offside (to the left) of some child of <prod2rascal(p)> using a failing syntax action that compares annotations @loc.start.column", u@\loc)];
, (u.src).begin.column >= (y.src).begin.column
, (u.src).begin.line < (y.src).end.line) {
return [error("You might declare nested <prod2rascal(q)> offside (to the left) of some child of <prod2rascal(p)> using a failing syntax action that compares annotations @loc.start.column", u.src)];
}

return [];
}

list[Message] associativityCauses(Tree x, Tree y) {
if (/appl(p,[appl(p,_),*_]) := x, /Tree t:appl(p,[*_,appl(p,_)]) := y) {
return [error("This rule [<alt2rascal(p)>] may be missing an associativity declaration (left, right, non-assoc)", t@\loc)];
return [error("This rule [<alt2rascal(p)>] may be missing an associativity declaration (left, right, non-assoc)", t.src)];
}

if (/appl(p,[appl(p,_),*_]) := y, /Tree t:appl(p,[*_,appl(p,_)]) := x) {
return [error("This rule [<alt2rascal(p)>] may be missing an associativity declaration (left, right, non-assoc)", t@\loc)];
return [error("This rule [<alt2rascal(p)>] may be missing an associativity declaration (left, right, non-assoc)", t.src)];
}

return [];
Expand Down
6 changes: 3 additions & 3 deletions src/org/rascalmpl/library/analysis/text/search/Grammars.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Analyzer commentAnalyzerFromGrammar(type[&T <: Tree] grammar) = analyzer(comment
Tokenizer tokenizerFromGrammar(type[&T <: Tree] grammar) = tokenizer(list[Term] (str input) {
try {
tr = parse(grammar, input, |lucene:///|, allowAmbiguity=true);
return [term("<token>", token@\loc, "<type(token.prod.def,())>") | token <- tokens(tr, isToken) ];
return [term("<token>", token.src, "<type(token.prod.def,())>") | token <- tokens(tr, isToken) ];
}
catch ParseError(_):
return [term(input, |lucene:///|(0, size(input)), "entire input")];
Expand All @@ -24,7 +24,7 @@ Tokenizer tokenizerFromGrammar(type[&T <: Tree] grammar) = tokenizer(list[Term]
Tokenizer identifierTokenizerFromGrammar(type[&T <: Tree] grammar) = tokenizer(list[Term] (str input) {
try {
tr = parse(grammar, input, |lucene:///|, allowAmbiguity=true);
return [term("<token>", token@\loc, "<type(token.prod.def, ())>") | token <- tokens(tr, isToken), isLexical(token)];
return [term("<token>", token.src, "<type(token.prod.def, ())>") | token <- tokens(tr, isToken), isLexical(token)];
}
catch ParseError(_):
return [term(input, |lucene:///|(0, size(input)), "entire input")];
Expand All @@ -34,7 +34,7 @@ Tokenizer identifierTokenizerFromGrammar(type[&T <: Tree] grammar) = tokenizer(l
Tokenizer commentTokenizerFromGrammar(type[&T <: Tree] grammar) = tokenizer(list[Term] (str input) {
try {
tr = parse(grammar, input, |lucene:///|, allowAmbiguity=true);
return [term("<comment>", comment@\loc, "<type(comment.prod.def,())>") | comment <- tokens(tr, isComment)];
return [term("<comment>", comment.src, "<type(comment.prod.def,())>") | comment <- tokens(tr, isComment)];
}
catch ParseError(_):
return [term(input, |lucene:///|(0, size(input)), "entire input")];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public tuple[set[Production] prods, Maybe[Symbol] \start] rule2prod(SyntaxDefini
return <{prod2prod(\lex("<n>"), p)}, nothing()>;
case \keyword(nonterminal(Nonterminal n), Prod p) :
return <{prod2prod(keywords("<n>"), p)}, nothing()>;
default: { iprintln(sd); throw "unsupported kind of syntax definition? <sd> at <sd@\loc>"; }
default: { iprintln(sd); throw "unsupported kind of syntax definition? <sd> at <sd.src>"; }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void storeParsersForModules(set[loc] moduleFiles, PathConfig pcfg) {

void storeParsersForModules(set[Module] modules, PathConfig pcfg) {
for (m <- modules) {
storeParserForModule("<m.header.name>", m@\loc, modules, pcfg);
storeParserForModule("<m.header.name>", m.src, modules, pcfg);
}
}

Expand Down
Loading