A hack to distinguish if..else from else: in case.

The old BIRD grammar needs two lookaheads to distinguish if..else from
else: in case, which caused the parser to fail on some combinations of
both expressions.

This patch replaces two tokens 'else' ':' by one token 'else:' to fix
that.
This commit is contained in:
Ondrej Zajicek 2011-03-23 12:49:53 +01:00
parent 6bcef22580
commit 26d92bb892
5 changed files with 16 additions and 10 deletions

View file

@ -137,6 +137,11 @@ WHITE [ \t]
return NUM; return NUM;
} }
else: {
/* Hack to distinguish if..else from else: in case */
return ELSECOL;
}
({ALPHA}{ALNUM}*|[']({ALNUM}|[-])*[']) { ({ALPHA}{ALNUM}*|[']({ALNUM}|[-])*[']) {
if(*yytext == '\'') { if(*yytext == '\'') {
yytext[yyleng-1] = 0; yytext[yyleng-1] = 0;

View file

@ -48,7 +48,7 @@ CF_DECLS
struct timeformat *tf; struct timeformat *tf;
} }
%token END CLI_MARKER INVALID_TOKEN %token END CLI_MARKER INVALID_TOKEN ELSECOL
%token GEQ LEQ NEQ AND OR %token GEQ LEQ NEQ AND OR
%token PO PC %token PO PC
%token <i> NUM ENUM %token <i> NUM ENUM

View file

@ -837,7 +837,7 @@ prefix and prefix (returning true if first prefix is more specific than second o
<M>command_1</M>; <M>command_2</M>; <M>...</M> }</cf> instead of either command. The <cf>else</cf> <M>command_1</M>; <M>command_2</M>; <M>...</M> }</cf> instead of either command. The <cf>else</cf>
clause may be omitted. If the <cf><m>boolean expression</m></cf> is true, <cf><m>command1</m></cf> is executed, otherwise <cf><m>command2</m></cf> is executed. clause may be omitted. If the <cf><m>boolean expression</m></cf> is true, <cf><m>command1</m></cf> is executed, otherwise <cf><m>command2</m></cf> is executed.
<p>The <cf>case</cf> is similar to case from Pascal. Syntax is <cf>case <m/expr/ { else | <p>The <cf>case</cf> is similar to case from Pascal. Syntax is <cf>case <m/expr/ { else: |
<m/num_or_prefix [ .. num_or_prefix]/: <m/statement/ ; [ ... ] }</cf>. The expression after <m/num_or_prefix [ .. num_or_prefix]/: <m/statement/ ; [ ... ] }</cf>. The expression after
<cf>case</cf> can be of any type which can be on the left side of the &tilde; operator and anything that could <cf>case</cf> can be of any type which can be on the left side of the &tilde; operator and anything that could
be a member of a set is allowed before <cf/:/. Multiple commands are allowed without <cf/{}/ grouping. be a member of a set is allowed before <cf/:/. Multiple commands are allowed without <cf/{}/ grouping.

View file

@ -305,11 +305,11 @@ switch_body: /* EMPTY */ { $$ = NULL; }
$$->data = $4; $$->data = $4;
$$->left = $1; $$->left = $1;
} }
| switch_body ELSE ':' cmds { | switch_body ELSECOL cmds {
$$ = f_new_tree(); $$ = f_new_tree();
$$->from.type = T_VOID; $$->from.type = T_VOID;
$$->to.type = T_VOID; $$->to.type = T_VOID;
$$->data = $4; $$->data = $3;
$$->left = $1; $$->left = $1;
} }
; ;

View file

@ -31,10 +31,11 @@ int i;
i = arg2; i = arg2;
case arg1 { case arg1 {
2: print "dva"; print "jeste jednou dva"; 2: printn "dva, "; printn "jeste jednou dva";
3 .. 5: print "tri az pet"; 3 .. 5: if arg2 < 3 then printn "tri az pet";
else: print "neco jineho"; else: printn "neco jineho";
} }
print;
} }
function fifteen() function fifteen()
@ -247,7 +248,7 @@ string s;
callme ( 2, 2 ); callme ( 2, 2 );
callme ( 2, 2 ); callme ( 2, 2 );
callme ( 3, 2 ); callme ( 3, 2 );
callme ( 4, 2 ); callme ( 4, 4 );
callme ( 7, 2 ); callme ( 7, 2 );
i = fifteen(); i = fifteen();