Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Using variables with predefined functions
Using variables with predefined functions [message #899409] Tue, 31 July 2012 17:48 Go to next message
Charalampos Alexopoulos is currently offline Charalampos AlexopoulosFriend
Messages: 9
Registered: July 2012
Junior Member
Hi

I am creating the grammar for the OpenSCAD (www.openscad.org). A valid snippet of the OpenSCAD code is:

a=-13;
b=a*2;
c=2*abs(a);
a=(b/c)*6;

I start from the arithmetics example and implement most of the aspects of the language, but i have some problems. Here is a simplified version of my grammar which relate to my problems:

Code:

(imports+=Import)*
(statements+=Statement)*;

Import:
'include<' importedNamespace=ImportName '>';

ImportName:
ID ('.' 'scad')?;

Statement:
ModuleDeclaration | Command;

Command:
Variable | ModuleCall ;

Predefined:
ABS | SQRT
;

SQRT:
'sqrt'
;


ABS:
'abs'
;




AbstractDefinition:
DeclaredParameter | Variable | Function ;

ModuleDeclaration:
'module' name=ID '(' (args+=DeclaredParameter (',' args+=DeclaredParameter)*)? ')' '{' command+=Command*'}';

ModuleCall:
method = [ModuleDeclaration] '(' (args+=DeclaredParameter (',' args+=DeclaredParameter)*)? ')' ';'
;

DeclaredParameter:
name=ID ('=' ('+' | '-')? parameters=Expression)?;

Function:
name=Predefined '(' ('+' | '-')? parameters=Expression ')';

Variable:
name=ID '=' ('+' | '-')? expression=Expression ';';

Expression:
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:
'(' Expression ')' | {NumberLiteral} value=NUMBER
| {FunctionCall} func=[AbstractDefinition] ('(' args+=Expression (',' args+=Expression)* ')')?;

terminal NUMBER returns ecore::EBigDecimal:
('0'..'9')* ('.' ('0'..'9')+)?;

terminal INT returns ecore::EInt:
'this one has been deactivated';


It generate the code and run with no errors or warnings, but i have two problems in the sample code. In the predefined function 'abs ' i get the message "no viable alternative at input 'abs' and in the definitions of variable 'a' i get the message "duplicate statement 'a'". The language aloud duplicate definition of variable.
Re: Using variables with predefined functions [message #899466 is a reply to message #899409] Wed, 01 August 2012 02:52 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2500
Registered: July 2009
Senior Member
Have not looked in detail, but I suspect there is a problem with
references - remember that something like func= [AbstractDefinition]
really means func = [AbstractDefinition | ID ] - which means "parse and
ID and use that to reference an instance of AbstractDefinition with
matching name.

So... your functions 'abs' and 'sqr' are declared as keywords, and the
lexer will not produce an ID token for these.

You can try something like:

FUNCID = 'abs' | 'sqr' | ID ;
and reference with
func = [AbstractDefinition|FUNCID]

Hope that helps.
- henrik

On 2012-31-07 19:48, Charalampos Alexopoulos wrote:
> Hi
>
> I am creating the grammar for the OpenSCAD (www.openscad.org). A valid
> snippet of the OpenSCAD code is:
>
> a=-13;
> b=a*2;
> c=2*abs(a);
> a=(b/c)*6;
>
> I start from the arithmetics example and implement most of the aspects
> of the language, but i have some problems. Here is a simplified version
> of my grammar which relate to my problems:
>
> Code:
>
> (imports+=Import)* (statements+=Statement)*;
>
> Import:
> 'include<' importedNamespace=ImportName '>';
>
> ImportName:
> ID ('.' 'scad')?;
>
> Statement:
> ModuleDeclaration | Command;
>
> Command:
> Variable | ModuleCall ;
>
> Predefined:
> ABS | SQRT
> ;
>
> SQRT:
> 'sqrt'
> ;
>
>
> ABS:
> 'abs'
> ;
>
>
>
>
> AbstractDefinition:
> DeclaredParameter | Variable | Function ;
>
> ModuleDeclaration:
> 'module' name=ID '(' (args+=DeclaredParameter (','
> args+=DeclaredParameter)*)? ')' '{' command+=Command*'}';
>
> ModuleCall:
> method = [ModuleDeclaration] '(' (args+=DeclaredParameter (','
> args+=DeclaredParameter)*)? ')' ';'
> ;
>
> DeclaredParameter:
> name=ID ('=' ('+' | '-')? parameters=Expression)?;
>
> Function:
> name=Predefined '(' ('+' | '-')? parameters=Expression ')';
>
> Variable:
> name=ID '=' ('+' | '-')? expression=Expression ';';
>
> Expression:
> 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:
> '(' Expression ')' | {NumberLiteral} value=NUMBER
> | {FunctionCall} func=[AbstractDefinition] ('('
> args+=Expression (',' args+=Expression)* ')')?;
>
> terminal NUMBER returns ecore::EBigDecimal:
> ('0'..'9')* ('.' ('0'..'9')+)?;
>
> terminal INT returns ecore::EInt:
> 'this one has been deactivated';
>
>
> It generate the code and run with no errors or warnings, but i have two
> problems in the sample code. In the predefined function 'abs ' i get the
> message "no viable alternative at input 'abs' and in the definitions of
> variable 'a' i get the message "duplicate statement 'a'". The language
> aloud duplicate definition of variable.
Re: Using variables with predefined functions (Solved) [message #900051 is a reply to message #899466] Fri, 03 August 2012 16:48 Go to previous message
Charalampos Alexopoulos is currently offline Charalampos AlexopoulosFriend
Messages: 9
Registered: July 2012
Junior Member
Thank you for the explanation.
Your suggestion didn't work but help me to improve my poor understanding of the Xtext.
I put a solution to my problem in case somebody helped by this.
First of all my approach was completely wrong, even when i make it to work it produce a wrong behavior. So the solution was to immediate add the Function to PrimaryExpression with 'syntactic predicate'.

PrimaryExpression returns Expression:
'(' Expression ')' | {NumberLiteral} value=NUMBER
| => Function
| {FunctionCall} func=[AbstractDefinition ] ('(' args+=Expression (',' args+=Expression)* ')')?;
Previous Topic:Couldn't resolve reference to JvmIdentifiableElement 'generateStub'.
Next Topic:Computer Algebra Language
Goto Forum:
  


Current Time: Mon Nov 24 03:08:50 GMT 2014

Powered by FUDForum. Page generated in 0.03785 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software