[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