[antlr-interest] How to use predicate or workaround the bug ?

Ilia Kantor ilia at obnovlenie.ru
Thu Jan 4 11:31:11 PST 2007


> > The ultimate question is  how to make 'input.index()==0' to work,
> > but 'true'
> > fails to compile also..
>
> works fine for me.  input.index()==0 should be fine too.

You took my grammar, and it compiled for you? That would be strange indeed!

Is that only me having problems with such grammar ? 

Anyone, please run ANTLR3 on it ?!? 

========================
grammar CommonRule;


options {
   	superClass=CommonRuleParentParser; 
   	output=AST;
}




@parser::header {
    package grammar.parser;
    
	import grammar.*;	
	import grammar.parser.*;
	import grammar.parser.exception.*;

    import org.apache.log4j.Logger;
    import java.util.Stack;
    import java.util.ArrayList;
}

@rulecatch { }

@parser::members {

    private static Logger logger = Logger.getLogger(CommonRuleParser.class);    

    protected String getTokenName(Token tok) {
    	return tokenNames[tok.getType()];
    }
}



@lexer::header {
    package grammar.parser;	
    import grammar.*;
    
}

/* putting this to tokens { .. } causes antlrworks bugs like "...no lexer rule 
for IF..." */
IF	:	{false}? .;
THEN	:	{false}? .;
ELSE	:	{false}? .;
EVAL	:	{false}? .;
TEXT	:	{false}? .;
GET_PROPERTY	:	{false}? .;
GET_PART	:	{false}? .;

LCURL	:	'{';
RCURL	:	'}';

GET_SCOPE_VALUE
	:	'#';

CONTROL
	:	'~';
	
SEMI:	';';

DOT	:	'.';

MINUS
	:	'-';

GT	:	'>';

SPECIAL_CHAR
	:	'`' | '!' | '@' | '$' | '%' | '^' | '&' | '*' | '(' | ')' |  
	'+' | '=' | '[' | ']' | ':' | '\'' | '"' | '\\' | '|' | ',' | '<' |
	 '/' | '?';
	


fragment WS_CHAR  :
       (' '|'\r'|'\t'|'\u000C'|'\n' )
    ;
    
WS	:	WS_CHAR+;

// not SPECIAL_CHAR not WS_CHAR
WORD:	
{
	// check if previous character was CONTROL
	Boolean afterControl = input.index()>0 && input.LT(-1)=='~';
}
	(~ ('`' | '!' | '@' | '$' | '%' | '^' | '&' | '*' | '(' | ')' |  
	'+' | '=' | '[' | ']' | ':' | '\'' | '"' | '\\' | '|' | ',' | '<' | '/' | '?'
	| '{' 
	| '~'
	| '}'
	| '#'
	| ';'
	| '.'
	| '-'
	| '>'	
	| ' '|'\r'|'\t'|'\u000C'|'\n' ) )+ 
{
    if (afterControl) {
    	// output WORDs as commands if after control
		if (getText().equalsIgnoreCase("if")) $type=IF;
		else if (getText().equalsIgnoreCase("else")) $type=ELSE;
		else if (getText().equalsIgnoreCase("then")) $type=THEN;
	}
}
;



document
	:	exprs;


exprs:
        (expr)+
;


expr:
(
        expr_no_semi -> expr_no_semi | 
        SEMI -> TEXT[$SEMI]
)
;

exprs_no_semi
        :       (expr_no_semi)+
;


expr_no_semi 
        :
                (expr_simple) | (curly_block)
        ;



exprs_simple 
        :       (expr_simple)+
        ;

/* expression without curl at start and ; */
expr_simple 
        :
        command   
        | rule_call 
        | text
;


command:
         command_eval |
         command_if  
;


command_if
       :
        CONTROL IF LCURL exprs? command_if_part_then command_if_part_else? 
RCURL ->
        ^(IF exprs? command_if_part_then command_if_part_else?)
;


command_if_part_else:
        CONTROL ELSE exprs? -> ^(ELSE exprs?)
;

command_if_part_then 
        : CONTROL THEN exprs? -> ^(THEN exprs?)
;



command_eval:
        CONTROL LCURL exprs? RCURL -> ^(EVAL exprs?)
;



rule_call: GET_SCOPE_VALUE WORD -> ^(GET_SCOPE_VALUE WORD) |
	GET_SCOPE_VALUE LCURL WORD rule_long_def_part* RCURL -> ^(GET_SCOPE_VALUE 
WORD rule_long_def_part*)
;

rule_long_def_part
	:	MINUS GT WORD -> ^(GET_PROPERTY WORD) | 
		DOT WORD -> ^(GET_PART WORD)
	;
	

curly_block
	:	
	 {true}? LCURL exprs? RCURL -> TEXT[$LCURL] exprs? TEXT[$RCURL] |
	   LCURL exprs? RCURL -> exprs? 
;
/*
curly_block
	:	
	 LCURL exprs? RCURL -> TEXT[$LCURL] exprs? TEXT[$RCURL]  
;*/


text:
	DOT -> TEXT[$DOT] | MINUS -> TEXT[$MINUS] | WORD -> TEXT[$WORD] 
	| WS -> TEXT[$WS] | GT -> TEXT[$GT] | SPECIAL_CHAR -> TEXT[$SPECIAL_CHAR]
;


More information about the antlr-interest mailing list