Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Yet another parsing rule question (cross reference)(Noob)
Yet another parsing rule question (cross reference) [message #1194497] Mon, 18 November 2013 14:45 Go to next message
Gary Worsham is currently offline Gary WorshamFriend
Messages: 157
Registered: September 2013
Senior Member
Bottom line on this one: I need to be able to parse a literal OR a cross reference, but can't figure out how to do this.

Supposing I had these statements in my DSL file:

equ offset 25
mem buffer 300

rdax buffer+offset, 0.5


I'd like the "buffer + offset" part to get converted to "buffer + 25".

My DSL needs to consume memory expressions with the following possible structures:

buffer
buffer+25

buffer^
buffer^+25
buffer^-25

buffer#
buffer#-25

Not that it really matters, but "buffer" by itself represents the start address of the buffer, buffer^ represents the middle of the buffer, and buffer# represents the end of the buffer. That's why buffer-25 and buffer#+25 are not valid because they represent addresses outside of the allocated memory space.

Here's my current rule, which picks up all of these as a single string which I can manipulate in Java to get the correct numeric representation:

SPINMEM: 
	ID ('#' | '^')? (('+' | '-') (INT | ID))?
;


You'll notice that I have the possibility of an ID at the end, so that I can also get expressions like:

buffer+offset

where earlier, offset was declared like this (with corresponding rules also shown):

equ offset 25

Equate:
	'equ' ename = ID value = SPINDOUBLE 
;

SPINDOUBLE: 
	'-'? (ID | (INT ( '.' INT)?))
;



Anyway, my currently defined rule will pick up an expression like

buffer+offset


and convert the whole thing to a string available to my Java code. Now since several DSL instructions reference the same type of memory expression, dealing with that is a separate method, meaning that the reference to "offset" is not in the scope where "offset" was declared.

I tried changing "SPINMEM" rule to include a cross reference to a "mem" statement, but Xtext did not like it:

SPINMEM: 
	ID ('#' | '^')? (('+' | '-') (INT | [Mem]))?
;


Gives the error: "No viable alternative at '['". So it really wasn't expecting that. The examples suggest I need to create a "super class" but I'm missing how to do that exactly. Thanks for any suggestions.

GW

[Updated on: Tue, 19 November 2013 05:19]

Report message to a moderator

Re: Yet another parsing rule question (cross reference) [message #1196881 is a reply to message #1194497] Tue, 19 November 2013 16:49 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6495
Registered: July 2009
Senior Member
Hi,

you can only jave crossrefs in ParserRules that create objects.
therefore you should at least use an assignment

(=> no cross refs in datatype rules)
Re: Yet another parsing rule question (cross reference) [message #1197005 is a reply to message #1196881] Tue, 19 November 2013 18:05 Go to previous messageGo to next message
Gary Worsham is currently offline Gary WorshamFriend
Messages: 157
Registered: September 2013
Senior Member
Thanks, that does appear to match my experience. Also, I think it will be helpful to break the expression into more than 1 token.

So for example the worst case, something like:

buffer#-256

or

buffer^+offset

would want to get broken into two or three tokens to be consumed as individual arguments by the parser. So rather than only having "buffer#-offset" to work with, I could have "buffer#" or "buffer" or "buffer^" and either null or "+256" or "-offset". If I want to use "offset" as a literal variable name in my template code, it might be better to break it up further, ("+" | "-") followed by (INT | ID). I haven't experimented with it yet.

I can even probably avoid needing to use a cross reference at all, by coming up with a special data type rule for this type of variable in the code, e.g.

MEMOFFSET: 'memofs' name = ID value = INT;

This would then generate Java code such as:

int name = value;

Then later, substitute "value" in the template code where the instruction references this constant.

Thanks,

GW

[Updated on: Tue, 19 November 2013 18:12]

Report message to a moderator

Re: Yet another parsing rule question (cross reference) [message #1197120 is a reply to message #1197005] Tue, 19 November 2013 19:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6495
Registered: July 2009
Senior Member
so what about

SPINMEM:
stuff = ID ('#' | '^')? (('+' | '-') (value=INT | mem=[Mem]))?
;
Re: Yet another parsing rule question (cross reference) [message #1198740 is a reply to message #1197120] Wed, 20 November 2013 13:37 Go to previous messageGo to next message
Gary Worsham is currently offline Gary WorshamFriend
Messages: 157
Registered: September 2013
Senior Member
Hi Christian, your suggestion looks promising. It requires some other changes to my code so I may have some other questions.

The first question is "how can I keep the trailing '#' or '^' attached to the end of the first token"? Would I have to separate that out as a data type rule?

Thanks again!

GW

[Updated on: Wed, 20 November 2013 14:36]

Report message to a moderator

Re: Yet another parsing rule question (cross reference) [message #1198772 is a reply to message #1198740] Wed, 20 November 2013 14:00 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6495
Registered: July 2009
Senior Member
Hi,

what do you mean by "keep" you want to preserve the text
then a datatype rule world be fine
Re: Yet another parsing rule question (cross reference) [message #1198831 is a reply to message #1198772] Wed, 20 November 2013 14:35 Go to previous messageGo to next message
Gary Worsham is currently offline Gary WorshamFriend
Messages: 157
Registered: September 2013
Senior Member
Yes, I already tried it, works great. I need to keep the # or ^ on the end of the parsed token so that the Java code can interpret the offset properly. Thanks, GW
Re: Yet another parsing rule question (cross reference) [message #1200101 is a reply to message #1198831] Thu, 21 November 2013 04:49 Go to previous message
Gary Worsham is currently offline Gary WorshamFriend
Messages: 157
Registered: September 2013
Senior Member
OK, now I have another little subtle issue.

Here's my relevant rules in my xtext grammar:

ReadDelay: 'rda' arg1 = SPINMEM ',' arg2 = SPINDOUBLE;

SPINMEM: 
	buffer = SPINBUF (value = INT | offset=[Offset])?
;

SPINBUF: ID('#'|'^')?('+'|'-')?;

SPINDOUBLE: 
	'-'? (ID | (INT ( '.' INT)?))
;


and here's the section which consumes it in the generator xtend:

	def genReadDelay(ReadDelay inst) { 
		if(inst.getArg1.getOffset.name != "") {'''
		// get offset 
		sfxb.FXreadDelay("«inst.getArg1.getBuffer»", «inst.getArg1.getOffset.name», «inst.getArg2»);
		'''
		} 
		else
		if(inst.getArg1.getValue != 0) {'''
		// get value
		sfxb.FXreadDelay("«inst.getArg1.getBuffer»", «inst.getArg1.getValue», «inst.getArg2»);
		'''
		} 
		else {'''
		// default 0 
		sfxb.FXreadDelay("«inst.getArg1.getBuffer»", 0, «inst.getArg2»);
		'''
		} 
	}


I have 3 possibilities for the "offset" part of the memory expression.

#1 - it's not there at all, and the value should be set to 0.
#2 - it's an INT literal, and the value should be that literal.
#3 - it's a cross-reference to an Offset, and the value parsed should be the name of that Offset.

So far I am only able to get the correct answer to cases #1 and #2. Any attempts to access the cross reference when there isn't one defined result in a null pointer exception.

[Updated on: Thu, 21 November 2013 13:21]

Report message to a moderator

Previous Topic:Beginner Question: Xtext Error RULE_ID
Next Topic:duplicate validation
Goto Forum:
  


Current Time: Wed Nov 26 09:18:31 GMT 2014

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

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