Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » conflict with parenthesis
conflict with parenthesis [message #900979] Thu, 09 August 2012 05:40 Go to next message
Laigle jérôme is currently offline Laigle jérôme
Messages: 26
Registered: August 2012
Junior Member
Hi,
I'm working on a DSL and i have some conflict with "Call" parenthesis
I need to support this type of instruction for example:

dcl a%
proc myProcedure()
endproc
proc myProcedure2()
endproc
proc myProcedure3()
endproc

#if myProcedure()>0
call myProcedure2()
#endif
#if a<0
myProcedure3()
#endif

It's just a part of my dsl:

Procedure:
('extern')?('forward')?'proc' name=ID (',''d')? ('('argument+=[VariableDeclaration] (',' argument+=[VariableDeclaration])* ')')? ((':' return+=[VariableDeclaration])*)?
instructions+=Instruction*
'endproc'
;
Instruction:
ControleStructure|VariableDeclaration|VariableAssignment|Call
;
Call:
('call')? procedure=[Procedure] '(' (argument+=[VariableDeclaration] (',' argument+=[VariableDeclaration])*)? ')'
;

VariableDeclaration:
'dcl' name = ID type = Type ('like' variable=[VariableDeclaration])?
('endloc')?('[,S]')?
;
Type:
ShortNumericType | NumericType | StringType | BCDType
;

ShortNumericType:
{ShortNumericType}'#';

NumericType:
{NumericType}'%';

StringType:
{StringType}'$'('='size=INT)?
;
BCDType:
{BCDType}('='size=INT)?;

VariableAssignment:
dcl=[VariableDeclaration]'='expr=Expression
;
Expression :
CompareOperator;

CompareOperator returns Expression:
ConditionalOR(( {Equality.left=current}'=='|{NoInclusion.left=current}'!='|{Different.left=current}'<>'|{Inferrior.left=current}'<'|{Superior.left=current}'>'|{SuperiorOrEqual.left=current}'>='|{InferriorOrEqual.left=current}'<=') right=ConditionalOR)*;

ConditionalOR returns Expression:
Addition (({ConditionalOR.left=current} 'or'|{ConditionalOX.left=current} 'ox'|{ConditionalAND.left=current} 'and'|{ConditionalNOT.left=current} 'not') right=Addition)*;
Addition returns Expression:
Multiplication (({Plus.left=current} '+' | {Minus.left=current} '-') right=Multiplication)*;

Multiplication returns Expression:
PrimaryExpression (({Multi.left=current} '*' | {Div.left=current} '/') right=PrimaryExpression)*;

PrimaryExpression returns Expression:
NumericInt|NumericReal|StringLiteral |Call
| VariableOperande
| '(' Expression ')'
;
StringLiteral:
stringValue=STRING
;
NumericInt:
value=INT;

NumericReal:
value=REAL;

ControleStructure:
Ifstatement
;

Ifstatement:
{Ifstatement}
"#if" (expressions+=Expression)*
instruction+=Instruction*

("#else"
instruction+=Instruction*
)?
"#endif"
;
VariableOperande:
variable=[VariableDeclaration]
;

terminal ID : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*;
terminal INT returns ecore::EInt: ('0'..'9')+;
terminal REAL returns ecore::EDouble : INT '.' INT;
terminal STRING :
'"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|'"') )* '"' |
"'" ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|"'") )* "'"
;

terminal SL_COMMENT : (';') !('\n'|'\r')* ('\r'? '\n')?;

terminal WS : (' '|'\t'|'\r'|'\n')+;



there is a conflict between VariableOperande and call parenthesis
and i have a second conflict when i define call in instruction

Maybe somebody has an idea or can point me into the right direction? Thanks in advance!
Best regards,
Jérôme
Re: conflict with parenthesis [message #901135 is a reply to message #900979] Thu, 09 August 2012 19:10 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik Lindberg
Messages: 2499
Registered: July 2009
Senior Member
Well, the grammar is ambiguous.
Your call rule starts with
Call:
('call')? procedure=[Procedure]

and since 'call' is optional, and [Procedure] is shorthand for
[Procedure| ID]

and

VariableOperande:
variable=[VariableDeclaration]

where [VariableDeclaration] is short for [VariableDeclaration| ID]

so...

when there is an ID, which one is it?

The solution is to make a call without 'call' an expression with higher
preceedence than multiplication. Your 'call' with explicit keyword can
still be a primary expression. You need a boolean to keep track of which
form the call statement has

ExplicitCall returns Call : {Call} explicitKeyword ?= 'call' ...;

and you need something like:

Multiplication returns Expression:
CallExpression (
( {Multi.left=current} '*'
| {Div.left=current} '/'
)
right=CallExpression)*
;

CallExpression returns Expression :
PrimaryExpression ({Call.funcExpr=current} '(' ... ')')?
;

You then have other issues, as the CallExpression will get a
VariableOperande as its funcExpr. You should make VariableDecl and
Procedure have a common superclass, then solve the issues with scoping
and validation.

Hope that helps
- henrik

On 2012-09-08 11:40, Laigle jérôme wrote:
> Hi,
> I'm working on a DSL and i have some conflict with "Call" parenthesis I
> need to support this type of instruction for example:
>
> dcl a%
> proc myProcedure()
> endproc
> proc myProcedure2()
> endproc
> proc myProcedure3()
> endproc
>
> #if myProcedure()>0
> call myProcedure2()
> #endif
> #if a<0
> myProcedure3()
> #endif
>
> It's just a part of my dsl:
>
> Procedure:
> ('extern')?('forward')?'proc' name=ID (',''d')?
> ('('argument+=[VariableDeclaration] (','
> argument+=[VariableDeclaration])* ')')? ((':'
> return+=[VariableDeclaration])*)? instructions+=Instruction*
> 'endproc'
> ;
> Instruction:
> ControleStructure|VariableDeclaration|VariableAssignment|Call
> ;
> Call:
> ('call')? procedure=[Procedure] '('
> (argument+=[VariableDeclaration] (','
> argument+=[VariableDeclaration])*)? ')'
> ;
>
> VariableDeclaration:
> 'dcl' name = ID type = Type ('like' variable=[VariableDeclaration])?
> ('endloc')?('[,S]')?
> ;
> Type:
> ShortNumericType | NumericType | StringType | BCDType
> ;
>
> ShortNumericType:
> {ShortNumericType}'#';
>
> NumericType:
> {NumericType}'%';
>
> StringType:
> {StringType}'$'('='size=INT)?
> ;
> BCDType:
> {BCDType}('='size=INT)?;
>
> VariableAssignment:
> dcl=[VariableDeclaration]'='expr=Expression
> ;
> Expression :
> CompareOperator;
>
> CompareOperator returns Expression:
> ConditionalOR((
> {Equality.left=current}'=='|{NoInclusion.left=current}'!='|{Different.left=current}'<>'|{Inferrior.left=current}'<'|{Superior.left=current}'>'|{SuperiorOrEqual.left=current}'>='|{InferriorOrEqual.left=current}'<=')
> right=ConditionalOR)*;
>
> ConditionalOR returns Expression:
> Addition (({ConditionalOR.left=current}
> 'or'|{ConditionalOX.left=current} 'ox'|{ConditionalAND.left=current}
> 'and'|{ConditionalNOT.left=current} 'not') right=Addition)*;
> Addition returns Expression:
> Multiplication (({Plus.left=current} '+' | {Minus.left=current}
> '-') right=Multiplication)*;
>
> Multiplication returns Expression:
> PrimaryExpression (({Multi.left=current} '*' | {Div.left=current}
> '/') right=PrimaryExpression)*;
>
> PrimaryExpression returns Expression:
> NumericInt|NumericReal|StringLiteral |Call
> | VariableOperande
> | '(' Expression ')' ;
> StringLiteral:
> stringValue=STRING
> ;
> NumericInt: value=INT;
> NumericReal:
> value=REAL;
>
> ControleStructure:
> Ifstatement
> ;
>
> Ifstatement:
> {Ifstatement}
> "#if" (expressions+=Expression)* instruction+=Instruction*
>
> ("#else"
> instruction+=Instruction*
> )?
> "#endif"
> ;
> VariableOperande:
> variable=[VariableDeclaration]
> ;
>
> terminal ID : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*;
> terminal INT returns ecore::EInt: ('0'..'9')+;
> terminal REAL returns ecore::EDouble : INT '.' INT;
> terminal STRING : '"' ( '\\'
> ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|'"') )* '"' |
> "'" ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') |
> !('\\'|"'") )* "'"
> ;
> terminal SL_COMMENT : (';') !('\n'|'\r')* ('\r'? '\n')?;
>
> terminal WS : (' '|'\t'|'\r'|'\n')+;
>
>
>
> there is a conflict between VariableOperande and call parenthesis and i
> have a second conflict when i define call in instruction
> Maybe somebody has an idea or can point me into the right direction?
> Thanks in advance!
> Best regards,
> Jérôme
Re: conflict with parenthesis [message #901546 is a reply to message #901135] Mon, 13 August 2012 06:41 Go to previous messageGo to next message
Laigle jérôme is currently offline Laigle jérôme
Messages: 26
Registered: August 2012
Junior Member
thank you for your help

In varableDeclaration i want to do a reference at type of variable declaration but i don't know how i can't do it
I want to do something like this:
VariableDeclaration:
'dcl' name = ID (type=Type | ('like' variable=[VariableDeclaration |Type])) ('endloc')?('[,S]')?
;

but it's not good grammar

if i understand you want to define something like this:

Expression :
CompareOperator;

CompareOperator returns Expression:
ConditionalOR(( /* {Inclusion.left=current} '='|*/{Equality.left=current}'=='|{NoInclusion.left=current}'!='|{Different.left=current}'<>'|{Inferrior.left=current}'<'|{Superior.left=current}'>'|{SuperiorOrEqual.left=current}'>='|{InferriorOrEqual.left=current}'<=') right=ConditionalOR)*;
thank you for your help

ConditionalOR returns Expression:
Addition (({ConditionalOR.left=current} 'or'|{ConditionalOX.left=current} 'ox'|{ConditionalAND.left=current} 'and'|{ConditionalNOT.left=current} 'not') right=Addition)*;
Addition returns Expression:
Multiplication (({Plus.left=current} '+' | {Minus.left=current} '-') right=Multiplication)*;

Multiplication returns Expression:
CallExpression (({Multi.left=current} '*' | {Div.left=current} '/') right=CallExpression)*;

CallExpression returns Expression :
PrimaryExpression (({Call.funcExpr=current} procedure=[Procedure] ',') right=PrimaryExpression )*;

PrimaryExpression returns Expression:
NumericInt|NumericReal|StringLiteral |ExplicitCall
| VariableOperande
| '(' Expression ')'
;

ExplicitCall returns Call : {Call} explicitKeyword ?= 'call' procedure=[Procedure] ('('argument+=[VariableDeclaration] (',' argument+=[VariableDeclaration])* ')')?;


but i have a problem when i realise test
@Test
def void testCallExpression()
{
val compilationUnit =
'''
program "MyProgramme"
segment 0

#if (myProc)
endif
proc myProc
endproc
eseg 0
end
'''.parse


val abalElement = compilationUnit.abalElements.head
val program = abalElement as Program
Assert::assertEquals("MyProgramme",program.name)
val segment= program.segment.get(0)

val inst= segment.instructions.get(0)
val controlStruct=inst as ControleStructure
val ifstatement= controlStruct as Ifstatement
val expression2= ifstatement.expression

Assert::assertTrue(expression2 instanceof Call)//expression2 can't be cast in call
val call=expression2 as Call
Assert::assertNotNull(call)
Assert::assertNotNull(call.procedure)
Assert::assertNotNull(call.procedure.name)
Assert::assertEquals('myProc',call.procedure.name)

}



maybe i do a error in my grammar
or i misunderstood your message...




Re: conflict with parenthesis [message #901722 is a reply to message #901546] Tue, 14 August 2012 06:26 Go to previous message
Laigle jérôme is currently offline Laigle jérôme
Messages: 26
Registered: August 2012
Junior Member
i define grammar like this but i have always problem with "implicit call"

Expression :
CompareOperator;

CompareOperator returns Expression:
ConditionalOR(( /* {Inclusion.left=current} '='|*/{Equality.left=current}'=='|{NoInclusion.left=current}'!='|{Different.left=current}'<>'|{Inferrior.left=current}'<'|{Superior.left=current}'>'|{SuperiorOrEqual.left=current}'>='|{InferriorOrEqual.left=current}'<=') right=ConditionalOR)*;

ConditionalOR returns Expression:
Addition (({ConditionalOR.left=current} 'or'|{ConditionalOX.left=current} 'ox'|{ConditionalAND.left=current} 'and'|{ConditionalNOT.left=current} 'not') right=Addition)*;
Addition returns Expression:
Multiplication (({Plus.left=current} '+' | {Minus.left=current} '-') right=Multiplication)*;

Multiplication returns Expression:
CallExpression (({Multi.left=current} '*' | {Div.left=current} '/') right=CallExpression)*;

CallExpression returns Expression :
//PrimaryExpression (({Call.funcExpr=current} procedure=[Procedure] /*','*/) right=PrimaryExpression )*;
PrimaryExpression (({Call.callExpr=current} '(' ')') right=PrimaryExpression )*;

PrimaryExpression returns Expression:
NumericInt|NumericReal|StringLiteral |ExplicitCall
| VariableOperande
| '(' Expression ')'
;

ExplicitCall returns Call : {Call} explicitKeyword ?= 'call' procedure=[Procedure] ('('argument+=[VariableDeclaration] (',' argument+=[VariableDeclaration])* ')')?

i think it's little thing who prevent to define "implicit call" but i don't find
Previous Topic:How to provide functionality on CTRL+click ?
Next Topic:Import all Files from given Folder
Goto Forum:
  


Current Time: Wed Aug 27 21:17:25 EDT 2014

Powered by FUDForum. Page generated in 0.01881 seconds