How to get parent scope for nested block? [message #1853811] |
Mon, 18 July 2022 23:42 |
Mykola Makhin Messages: 50 Registered: July 2018 |
Member |
|
|
If I have a DSL that allows me to declare variables in nested blocks, e.g. something like this:
blockA{var a:
$a // reference to var a
blockB{var b:
$a or $b // reference to var a and var b
blockC{var c:
$a or $b or $c // ref to a,b,c but not d
}
blockD {var d:
$a or $b or$d // ref to a,b,d but not c
}
}
}
How do I make such a scope provider?
If I do something like this:
@Override
public IScope getScope(EObject context, EReference reference) {
if (context instanceof ListElementReference) {
ListElementReference listElemRef = (ListElementReference) context;
ListFunction container = EcoreUtil2.getContainerOfType(listElemRef, ListFunction.class);
return container != null ? Scopes.scopeFor(Arrays.asList(container.getAlias())) : IScope.NULLSCOPE;
} else {
return super.getScope(context, reference);
}
}
I get scope for each individual block, but that's it - can't reference var in parent block.
In order to do that - I somehow need to get a reference to that parent block's scope. Is there a utility to look up existing scopes for eElement?
Just in case, full grammar:
grammar x.mvmn.permock.dsl.Dsl hidden(WS, ML_COMMENT, SL_COMMENT)
generate dsl "http://www.mvmn.x/permock/dsl/Dsl"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
Rule:
'if' conditions=Condition
('proxy' proxy=ProxyConf | 'respond' 'with' response=ResponseConf)?;
ProxyConf:
'url' proxyUrl=STRING;
ResponseConf:
('status' httpStatus?=INTEGER)? &
('content' content?=STRING)? & ('headers' headers=Headers?)?;
Headers:
headers+=Header (',' headers+=Header)*;
Header:
headerName=STRING ':' headerValue=STRING;
Condition:
OrCondition;
OrCondition returns Condition:
AndCondition ({OrCondition.left=current} 'or' right=AndCondition)*;
AndCondition returns Condition:
OptionalNegationCondition ({AndCondition.left=current} 'and' right=OptionalNegationCondition)*;
OptionalNegationCondition returns Condition:
BracketedCondition | {Negation} 'not' negated=BracketedCondition;
BracketedCondition returns Condition:
expression=Expression | '(' condition=Condition ')';
Expression:
left=Operand (op=Operator right=Operand)?;
Operand:
ref=Reference | const=Constant | listElementRef=ListElementReference;
ListFunction:
'{' op=ListOperation alias=ListElementAlias separator=':' condition=Condition '}';
ListElementAlias:
name=ID;
Reference hidden(WS):
name=Entity (prop=PropertyRef)?;
ListElementReference hidden(WS):
'$' name=[ListElementAlias|ID] (prop=PropertyRef)?;
PropertyRef hidden(WS):
('.' name=ID | '[' (name=STRING | index=INTEGER) ']' | listFunc=ListFunction)
(subPropery=PropertyRef)?;
enum Operator:
EQ='=' | NEQ='!=' | GT='>' | GTEQ='>=' | LT='<' | LTEQ='<=' | REGEX='~=';
Constant:
strVal=STRING | intVal=INTEGER | floatVal=FLOAT;
enum ListOperation:
FILTER='where' | ALL='all' | ANY='any';
Entity:
name=ID;
terminal FLOAT returns ecore::EDoubleObject:
INTEGER '.' INTEGER;
terminal INTEGER returns ecore::EIntegerObject:
('0'..'9')+;
terminal ID:
'^'? ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*;
terminal STRING:
'"' ('\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\' | '"'))* '"' |
"'" ('\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\' | "'"))* "'";
terminal ML_COMMENT:
'/*'->'*/';
terminal SL_COMMENT:
'//' !('\n' | '\r')* ('\r'? '\n')?;
terminal WS:
(' ' | '\t' | '\r' | '\n')+;
terminal ANY_OTHER:
.;
Sample code
if
a{
all a:
$a or b{
all b:
$a or $b or c{
all c:
$a or $b or $c
} or d{
all d:
$a or $b or $d
}
}
}
[Updated on: Mon, 18 July 2022 23:55] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.02649 seconds