%{ enum{TOKEN_A,TOKEN_B,TOKEN_C,TOKEN_D,OUTRO,FIM}; int token, nerros=0; void s(); /* protótipos */ void a(); void b(); %} %% a|A return TOKEN_A; b|B return TOKEN_B; c|C return TOKEN_C; d|D return TOKEN_D; . return OUTRO; \n return FIM; <> return FIM; %% void erro(char *s) { nerros++; printf("%s<-Erro %d: %s\n",yytext,nerros,s); exit(1); } void getToken() { printf("%s",yytext); token=yylex(); } void s() /* S-> aA | cS | dS */ { switch (token) { case TOKEN_A : getToken(); a(); break; case TOKEN_C : getToken(); s(); break; case TOKEN_D : getToken(); s(); break; default : erro("simbolo não reconhecido (esperava a,c ou d)"); } } void a() /* A-> aA | bB | cS | dS */ { switch (token) { case TOKEN_A : getToken(); a(); break; case TOKEN_B : getToken(); b(); break; case TOKEN_C : getToken(); s(); break; case TOKEN_D : getToken(); s(); break; default : erro("simbolo não reconhecido (esperava a,b,c ou d)"); } } void b() /* B-> aB | bB | cB | dB | vazio */ { switch (token) { case TOKEN_A : getToken(); b(); break; case TOKEN_B : getToken(); b(); break; case TOKEN_C : getToken(); b(); break; case TOKEN_D : getToken(); b(); break; } /* como pode ser vazio não dá erro */ } int main() { token=yylex(); /* vai buscar o 1º token */ s(); /* chama a produção inicial */ if (nerros==0 && token==FIM) printf("\nExpressao válida \n"); else erro("simbolo não reconhecido (esperava a,b,c,d ou fim)"); return 0; }