[antlr-interest] A look-ahead/rewind problem
Andreas Meyer
andreas.meyer at smartshift.de
Mon Mar 23 08:07:02 PDT 2009
I see. You have a parser rule "block_name" which reads a number of
tokens, each one character long. So, in effect, with input.LT(...) you
get one of the tokens/characters of the block_name rule. Why not put
this block_name into a lexer rule? You need to start Block_name with a
capital letter, to do this. LETTER and ALPHANUM should be turned into
fragments, so that they are not reported on their own. NEWLINE and WS
can be skipped with {skip();}
Andreas
Lukasz Guminski schrieb:
> 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');
> ALPHANUM : (LETTER|'0'..'9');
> BLOCK_BOUNDARY : 'BLOCK';
> NEWLINE : ( CR )? LF | CR;
> fragment CR :'\r';
> fragment LF : '\n';
> INSIGNIFICANT_CHAR:.;
>
> Input:
> BLOCK number1
> BLOCK number1
> BLOCK number1
> BLOCK number1
>
> Output:
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> *start of block: number1*
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> *start of block: number1*
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> *start of block: number1*
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> isBlockOpen() has been invoked with a value : n
> *start of block: number1*
>
> Just for the record, the output I'd like to get is (without debug):
> start of block: number1
> end of block: number1
> start of block: number1
> end of block: number1
>
> Thanks,
> Lucas
>
>
> 2009/3/23 Andreas Meyer <andreas.meyer at smartshift.de
> <mailto:andreas.meyer at smartshift.de>>
>
> If you are in a parser rule, input.LT(2) gives you the second-next
> _token_, instead of a character (as inside a lexer rule). So it
> should work.
>
> Andreas
>
> Lukasz Guminski schrieb:
> > input.LT(2).getText() does not work because it returns only the next
> > character. So when I have
> >
> > BLOCK with_a_very_long_name
> >
> > then LT(2) does not return the full name. Of course, I can set
> >
> > options{
> > k = 100;
> > }
> >
> > but that's not the solution.
> > Lucas
> >
> >
> > 2009/3/23 Andreas Meyer <andreas.meyer at smartshift.de
> <mailto:andreas.meyer at smartshift.de>
> > <mailto:andreas.meyer at smartshift.de
> <mailto:andreas.meyer at smartshift.de>>>
> >
> > Lukasz Guminski schrieb:
> > >
> > >
> > >
> > > I would suggest you try without the syntactic predicate,
> > turn your
> > > semantic predicate into a gated semantic predicate
> {...}? =>
> > such that
> > > it is forced to be evaluated:
> > >
> > > block_open: {is_block_open()}?=> BLOCK_BOUNDARY
> > >
> > >
> > > I cannot use a function without a parameter, because the
> decision
> > > bases on the name of a block. So the function needs to be
> of a form:
> > > /is_block_open(String blockName)/ function, and retrieving the
> > > parameter requires the parser to make a look-ahead. That's
> what
> > I need
> > > the syntactic predicate for.
> > Yes, that was meant as an example. If you need lookahead,
> you may also
> > consider using something like
> > input.LT(2).getText().equals(mystackofnames.top()). Anyway,
> have you
> > tried turning the sem. predicate into a gated sem. predicate
> (just
> > add a
> > => after the ?)
> >
> > Andreas
> >
> > List: http://www.antlr.org/mailman/listinfo/antlr-interest
> > Unsubscribe:
> >
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
> >
> >
>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>
>
More information about the antlr-interest
mailing list