[antlr-interest] Reading a string of fixed size

Alexandre Hamez alexandre.hamez at lip6.fr
Mon Aug 27 11:22:23 PDT 2007


Thanks, you help me a lot! I had to change a few things in order to  
make it run:

First, the value passed to FIXED_LENGTH_STRING must be computed in an  
action directly after the recognition of NUMBER.

CAMI_STRING
	@init{int nbToRead = 0;}
     	:
	NUMBER {nbToRead = Integer.parseInt($NUMBER.text);}
	':'
	fs=FIXED_LENGTH_STRING[nbToRead]
	{
		setText($fs.text);
	}
	;

The boolean expression in the predicate must not change the value  
tested because this part is called several time in the generated  
code, in the same loop. So I've decremented the value of len after  
each consumption of a character.

fragment
FIXED_LENGTH_STRING
	[int len]
	:
	( { len > 0 }?=> .{len--;})+
	;


On 27 août 07, at 18:41, Thomas Brandon wrote:

> On 8/28/07, Alexandre Hamez <alexandre.hamez at lip6.fr> wrote:
>> Thanks for your interest. But the fact is that I want to create a
>> Token with exactly NUMBER characters. The following characters will
>> match for other token. It's not an error if there are characters
>> which follow. Its mean that I can have something like that:
>>
>>         CAMI_STRING (',' CAMI_STRING)*
>>
>> ( for newcomers: CAMI_STRING : NUMBER ':' STRING where the size of
>> STRING is given by NUMBER).
>>
>>
>> Moreover, as a strange side effect of the following code, newlines
>> make the parser completely mad:
>>
>>> CAMI_STRING
>>>       :
>>>       NUMBER ':'
>>>       {
>>>               // Get the current position in stream
>>>               int start  = input.getCharPositionInLine();
>>>               // Computing the position of the last character of  
>>> the STRING to
>>> be read
>>>               int end = start + Integer.parseInt($NUMBER.text) - 1;
>>>               // Set the value of the returned value to STRING
>>>               setText(input.substring(start,end));
>>>               // Update the position in the stream
>>>               input.seek(end+1);
>>>       }
>>>       ;
> Seek takes an absolute index in the stream so you should get the
> location from input.index() rather than input.getCharPositionInLine().
> Also, you are going to get exceptions calling substring if a length is
> specified that extends past the end of the stream. You could call
> seek, which won't seek past the end of the stream and then check the
> resulting input to determine how many characters could actually be
> found. Or repeatedly call consume and check for EOF.
> Or a better solution might be to use predicates to handle the
> matching. Something like:
> CAMI_STRING
>     :   NUMBER ':' fs=FIXED_LENGTH_STRING[Integer.parseInt 
> ($NUMBER.text)]
>         { setText($fs.text); }
>     ;
>
> fragment
> FIXED_LENGTH_STRING[int len]
>     :   ( { len-- > 0 }?=> .)+ { len == 0 }?
>     ;
> should work. Or you may want to replace the second predicate in
> FIXED_LENGTH_STRING with code to record an error if all characters
> could not be matched, rather than handling the resulting predicate
> failure exception.
>
> Tom.
>

------------------------------------------------------------------------ 
---
Alexandre Hamez   LIP6 - MoVe / EPITA - LRDE
LIP6: tel: +33 1 44 27 31 92  / Bureau 818
104 Avenue du Président Kennedy 75016 Paris
http://www-src.lip6.fr/~Alexandre.Hamez


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2429 bytes
Desc: not available
Url : http://www.antlr.org/pipermail/antlr-interest/attachments/20070827/d57d25de/attachment.bin 


More information about the antlr-interest mailing list