Commit 767796ec authored by Daniel Honsel's avatar Daniel Honsel
Browse files

improved grammar and more scoping

parent 3ade7057
Loading
Loading
Loading
Loading
+17 −20
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ ModuleParList:
ModuleParameter:
	name=IDENTIFIER (ASSIGNMENTCHAR constExpr=ConstantExpression)?;


MultitypedModuleParList:
	{MultitypedModuleParList} (par+=ModulePar SEMICOLON?)*;

@@ -185,7 +184,7 @@ TemplateOrValueFormalParList:
	par+=TemplateOrValueFormalPar (COMMA par+=TemplateOrValueFormalPar);

TemplateOrValueFormalPar:
	FormalValuePar | FormalTemplatePar;
	value=FormalValuePar | template=FormalTemplatePar;

ConfigSpec:
	RunsOnSpec spec=SystemSpec?;
@@ -424,7 +423,6 @@ ComponentRefAssignment:
ArrayIdentifierRefAssignment:
	name=IDENTIFIER ASSIGNMENTCHAR ref=ArrayIdentifierRef;

	//TODO: check ref and treat ambiguity
FunctionActualPar:
	ArrayIdentifierRef | InLineTemplate | ComponentRef | {FunctionActualPar} MINUS;

@@ -432,7 +430,7 @@ ComponentRef:
	{ComponentRef} (ref=ComponentOrDefaultReference | SYSTEMKEYWORD | SELFOP | MTCKEYWORD);

ComponentOrDefaultReference:
	VariableRef | FunctionInstance;
	variable=VariableRef | function=FunctionInstance;

TestcaseInstance:
	EXECUTEKEYWORD LPAREN TestcaseRef LPAREN tcParams=TestcaseActualParList? RPAREN (COMMA (expr=Expression | MINUS)
@@ -503,7 +501,7 @@ ComponentReferenceOrLiteral:
	ComponentOrDefaultReference | {ComponentReferenceOrLiteral} MTCKEYWORD | {ComponentReferenceOrLiteral} SELFOP;

StartTCStatement:
	ComponentOrDefaultReference DOT STARTKEYWORD LPAREN function=FunctionInstance RPAREN;
	ref=ComponentOrDefaultReference DOT STARTKEYWORD LPAREN function=FunctionInstance RPAREN;

UnmapStatement:
	{UnmapStatement} UNMAPKEYWORD (spec=SingleConnectionSpec clause=ParamClause? | spec=AllConnectionsSpec
@@ -614,7 +612,6 @@ PortSendOp:
ToClause:
	{ToClause} TOKEYWORD (template=InLineTemplate | ref=AddressRefList | ALLKEYWORD COMPONENTKEYWORD);

// TODO: fix me!!!
FunctionDefList:
	(locDef=FunctionLocalDef | locInst=FunctionLocalInst) ws=WithStatement? sc=SEMICOLON?;

@@ -632,7 +629,7 @@ VarInstance:
	tempList=TempVarList));

VarList:
	var+=SingleVarInstance (COMMA var+=SingleVarInstance)*;
	variables+=SingleVarInstance (COMMA variables+=SingleVarInstance)*;

ReferencedType:
	SubTypeDefNamed | RecordDefNamed | SetDefNamed | PortDef | ComponentDef | UnionDefNamed | EnumDefNamed;
@@ -932,10 +929,10 @@ CreateOp:
RunningOp:
	ComponentId DOT RUNNINGKEYWORD;

	// TODO: complete this rule!
OpCall:
	ConfigurationOps | {OpCall} GETLOCALVERDICT | TimerOps | FunctionInstance | TestcaseInstance | ActivateOp /*|
	field+=ExtendedFieldReference* | TemplateOps field+=ExtendedFieldReference* */;
	configuration=ConfigurationOps | verdict=GETLOCALVERDICT | timer=TimerOps | function=FunctionInstance |
	testcase=TestcaseInstance | activate=ActivateOp | templateOps=TemplateOps fieldTemplate+=ExtendedFieldReference* |
	field+=ExtendedFieldReference+;

AliveOp:
	ComponentId DOT ALIVEKEYWORD;
@@ -1049,7 +1046,7 @@ ReferencedValue:
	ref=[RefValue|IDENTIFIER] ext+=ExtendedFieldReference*;

RefValue:
	SingleConstDef | ModuleParameter | SingleVarInstance | RecordOfDefNamed | SetOfDefNamed;
	SingleConstDef | ModuleParameter | SingleVarInstance | RecordOfDefNamed | SetOfDefNamed | FormalValuePar;

	// IDENTIFIER omitted
PredefinedValue:
@@ -1167,11 +1164,11 @@ ExtendedFieldReference:
	MINUS SQUARECLOSE;

LoopConstruct:
	ForStatement | WhileStatement | DoWhileStatement;
	forStm=ForStatement | whileStm=WhileStatement | doStm=DoWhileStatement;

ForStatement:
	FORKEYWORD LPAREN init=Initial SEMICOLON expression=BooleanExpression SEMICOLON assign=Assignment RPAREN
	block=StatementBlock;
	statement=StatementBlock;

WhileStatement:
	WHILEKEYWORD LPAREN expression=BooleanExpression RPAREN statement=StatementBlock;
@@ -1190,7 +1187,7 @@ ElseClause:
	ELSEKEYWORD statement=StatementBlock;

Initial:
	VarInstance | Assignment;
	variable=VarInstance | assignment=Assignment;

SelectCaseConstruct:
	SELECTKEYWORD LPAREN expression=SingleExpression RPAREN body=SelectCaseBody;
@@ -1203,14 +1200,14 @@ SelectCase:
	statement=StatementBlock;

FunctionDef:
	FUNCTIONKEYWORD name=IDENTIFIER LPAREN params=FunctionFormalParList? RPAREN runs=RunsOnSpec? returnType=ReturnType?
	statement=StatementBlock;
	FUNCTIONKEYWORD name=IDENTIFIER LPAREN parameterList=FunctionFormalParList? RPAREN runs=RunsOnSpec?
	returnType=ReturnType? statement=StatementBlock;

FunctionFormalParList:
	params+=FunctionFormalPar (COMMA params+=FunctionFormalPar)*;

FunctionFormalPar:
	FormalValuePar | FormalTimerPar | FormalTemplatePar | FormalPortPar;
	value=FormalValuePar | timer=FormalTimerPar | template=FormalTemplatePar | port=FormalPortPar;

FormalValuePar:
	(INPARKEYWORD | INOUTPARKEYWORD | OUTPARKEYWORD)? type=Type name=IDENTIFIER (ASSIGNMENTCHAR (expression=Expression |
+74 −33
Original line number Diff line number Diff line
@@ -11,30 +11,26 @@ import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.scoping.IScope

import static org.eclipse.xtext.scoping.Scopes.*
import java.util.ArrayList
import de.ugoe.cs.swe.tTCN3.FunctionDef
import de.ugoe.cs.swe.tTCN3.FunctionFormalPar
import de.ugoe.cs.swe.tTCN3.LoopConstruct
import de.ugoe.cs.swe.tTCN3.SingleVarInstance

class TTCN3ScopeHelper {

	// TODO: use some generic solution
	def static ModuleDefinitionsList getModuleDefList(EObject o) {
	def static Object findDesiredParent(EObject o, Class<?> t) {
		if (o.eContainer == null)
			null
		else if (o.eContainer instanceof ModuleDefinitionsList)
			o.eContainer as ModuleDefinitionsList
		else if (t.isAssignableFrom(o.eContainer.class))
			o.eContainer
		else
			o.eContainer.getModuleDefList
	}
	
	def static StatementBlock getStatementBlock(EObject o) {
		if (o.eContainer == null)
			null
		else if (o.eContainer instanceof StatementBlock)
			o.eContainer as StatementBlock
		else
			o.eContainer.getStatementBlock
			o.eContainer.findDesiredParent(t)
	}

	def static IScope moduleVariableScope(RefValue value) {
		val container = value.getModuleDefList
		val container = value.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList

		// TODO:  || it.def instanceof ModuleParDef
		val defs = container.definitions.filter[it.def instanceof ConstDef]
		val inner = newArrayList;
@@ -49,23 +45,68 @@ class TTCN3ScopeHelper {
	}

	def static IScope functionVariableScope(RefValue value) {
		val container = value.getStatementBlock
		val container = value.findDesiredParent(typeof(FunctionDef)) as FunctionDef

		if (container == null) {
			value.moduleVariableScope
		} else {
			val inner = newArrayList
			inner.addAll(value.functionParameter)
			if(container.statement != null) inner.addAll(container.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.moduleVariableScope)
		}
	}

	def static IScope loopVariableScope(RefValue value) {
		val loop = value.findDesiredParent(typeof(LoopConstruct)) as LoopConstruct
		val inner = newArrayList;

		if (loop != null && loop.forStm != null) {
			val list = loop.forStm.init.variable.list

			if (list != null) {
				for (SingleVarInstance v : list.variables) {
					inner.add(v)
				}
			}
			if(loop.forStm.statement != null) inner.addAll(loop.forStm.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.functionVariableScope)
		} else if (loop != null && loop.doStm != null) {
			if(loop.doStm.statement != null) inner.addAll(loop.doStm.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.functionVariableScope)
		} else if (loop != null && loop.whileStm != null) {
			if(loop.whileStm.statement != null) inner.addAll(loop.whileStm.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.functionVariableScope)
		} else {
			value.functionVariableScope
		}
	}

			for (FunctionDefList l : container.def.filter [it != null])
	def static private ArrayList<EObject> statementBlockVaraibles(StatementBlock sb, RefValue value) {
		val res = newArrayList

		for (FunctionDefList l : sb.def.filter[it != null]) {
			if (l.locDef.constDef != null) {
				val constDefList = l.locDef.constDef.defs as ConstList
				for (EObject d : constDefList.list) {
					if (d != value) inner.add(d)
					if(d != value) res.add(d)
				}
			}
			scopeFor(inner, value.moduleVariableScope)
		}

		res
	}

	def static private ArrayList<EObject> functionParameter(RefValue value) {
		val function = value.findDesiredParent(typeof(FunctionDef)) as FunctionDef
		val list = newArrayList;

		if (function.parameterList != null) {
			for (FunctionFormalPar v : function.parameterList.params.filter[it.value != null]) {
				list.add(v.value)
			}
		}
		list
	}

}
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
	
	def IScope scope_RefValue(RefValue value, EReference ref) {
		value.functionVariableScope
		value.loopVariableScope
	}
	
}
+2 −1
Original line number Diff line number Diff line
@@ -10,12 +10,13 @@ import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.validation.Check

import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList

class TTCN3Validator extends AbstractTTCN3Validator {

	@Check
	def checkUniqueNameNestedVariable(SingleConstDef variable) {
		val container = variable.getModuleDefList
		val container = variable.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList
		
		if (container == null) return;