[antlr-interest] A look-ahead/rewind problem
Lukasz Guminski
lguminski+antlr at gmail.com
Mon Mar 23 08:56:28 PDT 2009
I have just noticed the problem with alphanum. Regarding you opinion on
selecting of problems, I can say based on my experience that problems choose
you, and not vice versa:) I just need to solve this issue and I have no
choice here. And I admit I am not familiar with antlr. I only worked with
lex and yacc a long time ago.
Below is the working grammar. Thanks to Andreas and you for your help.
grammar block;
options{
k = 2;
}
@members{
Stack<String> stack = new Stack<String>();
boolean isBlockOpen(String name)
{
System.out.println("isBlockOpen() has been invoked with a value : " +
name);
return stack.size()==0||!stack.peek().equals(name);
}
}
data: blocks EOF;
blocks:block+;
block: block_open blocks? block_close;
block_open
: {isBlockOpen(input.LT(2).getText())}? =>
BLOCK_BOUNDARY BLOCK_NAME
{stack.push($BLOCK_NAME.text);System.out.println("start of block: " +
$BLOCK_NAME.text);};
block_close:BLOCK_BOUNDARY BLOCK_NAME {System.out.println("end of block: " +
$BLOCK_NAME.text);stack.pop();};
BLOCK_BOUNDARY : 'BLOCK';
BLOCK_NAME:LETTER ALPHANUM*;
SPACE : ' ' {skip();};
fragment ALPHANUM : (LETTER|'0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z');
NEWLINE : (( CR )? LF | CR) {skip();};
fragment CR :'\r';
fragment LF : '\n';
INSIGNIFICANT_CHAR:.;
Output:
isBlockOpen() has been invoked with a value : number1
isBlockOpen() has been invoked with a value : number1
*start of block: number1*
isBlockOpen() has been invoked with a value : number1
*end of block: number1*
isBlockOpen() has been invoked with a value : number1
isBlockOpen() has been invoked with a value : number1
*start of block: number1*
isBlockOpen() has been invoked with a value : number1
*end of block: number1*
Cheers,
Lucas
2009/3/23 Jim Idle <jimi at temporal-wave.com>
> Lukasz Guminski wrote:
>
> Thank you, but it doesn't work. LT(k) returns a character. I am sending you
> my grammar and the output I got.
>
> Grammar:
> grammar block;
> options{
> k = 3;
> }
>
> @members{
> Stack<String> stack = new Stack<String>();
> boolean isBlockOpen(String name)
> {
> System.out.println("isBlockOpen() has been invoked with a value : " +
> name);
> return stack.size()==0||!stack.peek().equals(name);
> }
> }
>
>
> data: blocks EOF;
> blocks:block+;
> block: block_open blocks? block_close;
> block_open
> : {isBlockOpen(input.LT(3).getText())}? =>
> BLOCK_BOUNDARY SPACE block_name NEWLINE
> {stack.push($block_name.text);System.out.println("start of block " +
> $block_name.text);};
> block_close:BLOCK_BOUNDARY SPACE block_name NEWLINE
> {System.out.println("end of block " + $block_name.text);stack.pop();};
> block_name:LETTER+ ALPHANUM*;
>
>
> SPACE : ' ';
> LETTER : ('a'..'z'|'A'..'Z');
>
>
> Well, you have LETTER as a non fragment rule, so you are always going to
> get this instead of ALPHANUM. You should be getting an ambiguity warning too
> I suspect and you block_name rule should be ID:
>
> fragment
> LETTER : ('a'..'z'|'A'..'Z');
> fragment
> ALPHANUM : (LETTER|'0'..'9');
>
> ID : LETTER ALPHANUM* ;
>
> Also, do you need the SPACE token? It will be a lot easier in the parser if
> you hide that and regardless, if the user has 2 spaces not one, then all
> your calculations will be out anyway. You should probably hide the
> insignificant_char token too.
>
> I think that you need to be doing this a different way really. You could
> easily do this in the lexer.
>
> Perhaps you should practice a bit on simpler problems before diving in to
> this one? I think you are suffering from not understanding the lexer/parser
> fundamentals yet.
>
> Jim
>
>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20090323/62d59e09/attachment.html
More information about the antlr-interest
mailing list