[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