![]() | ![]() | ![]() | Análise Léxical |
O objetivo da análise léxica é, dada uma sequência de texto:
Pertencem a um conjunto finito de tipos:
Comentários, directivas e macros do preprocessador, e espaços em branco não geram tokens!
float match0(char *s) /* find a zero */
{ if (!strncmp(s,"0.0", 3))
return 0.;
}
results in:
FLOAT ID(match0) LPAREN CHAR STAR ID(s) RPAREN LBRACE IF LPAREN BANG ID(strncmp) LPAREN ID(s) COMMA STRING(0.0) COMMA NUM(3) RPAREN RPAREN RETURN REAL(0.0) SEMI RBRACE EOF
Linguagem é um conjunto de sequências de símbolos (strings). Símbolos são obtidos de alfabetos.
Expressões regulares descrevem linguagens:
Exemplos: (0|1)*0; b*(abb*)*(a|eps); (a|b)*aa(a|b)*.
Abbrv: [abw-z], M+.
if {return IF;}
[a-z][a-z0-9]* {return ID;}
[0-9]+ {return NUM;}
([0-9]+"."[0-9]*)|
([0-9]+"."[0-9]*) {return REAL;}
("--"[a-z]*"\n")|
(" "|"\n"|"\t")+ {/* do nothing */}
. { error(); }
Regras:
Para implementar expressões regulares:
Autómato Combinado:
Codificação: matriz de transição
int edges[][256] = {
/* {......,0 1 2,..-..,e f g h i j...}*/
/* 0 */ {0,0,..,0,0,0,..0..,0,0,0,0,0,0...},
/* 1 */ {0,0,..,7,7,7,..9..,4,4,4,4,2,4...},
/* 2 */ {0,0,..,4,4,4,..0..,4,3,4,4,2,4...},
.....
}
Matriz de finalidade: cada estado final corresponde a acções.
Ideia:
Como gerar o nosso autómato finito?
Alguns exemplos, strings com tamanho múltiplo de 2 ou 3:
a mesma linguagem:
É fácil gerar autómatos não determínisticos a partir de expressões regulares:
Ideia: tentar todas as possibilidades ao mesmo tempo,
Cada tipo é associado a uma expressão regular e uma acção:
digits [0-9]+ substituido por {digits}.
{
/* Declarações C */
#include "tokens.h"
#include "errormsg.h"
union {int ival; string sval; double fval;}
yylval;
int charPos = 1;
#define ADJ (EM_tokPos=charPos,charPos+=yyleng)
%}
/* Definições Lex */
digits [0-9]+
%%
/* Expressões regulares e acções */
if {ADJ; return IF;}
[a-z][a-z0-9]* {ADJ;
yylval.sval=String(yytext);
return(ID);}
{digits} {ADJ; yylval.ival =
atoi(yytext);return(NUM);}
({digits}"."[0-9]*)|([0-9]*"."{digits})
{ADJ; yylval.fval=
atof(yytext);return(REAL);}
("--"[a-z]*"\n"*"\n")|(" "|"\n"|"\t")+ {ADJ;}
. {ADJ; EM_error("illegal character");}
Às vezes é conveniente misturar espaços e expressões regulares (eg, comentários).
%start INITIAL COMMENT
%%
<INITIAL>if {ADJ; return IF;}
<INITIAL>[a-z]+ {ADJ;
yylval.sval=String(yytext);
return(ID);}
<INITIAL>"(*" {ADJ; BEGIN COMMENT;}
<INITIAL>. {ADJ;
EM_error("illegal char");}
<COMMENT>"*)" {ADJ; BEGIN INITIAL;}
<COMMENT>. {ADJ;}
{BEGIN INITIAL; yyless(1);}
Comentários aninhados?
![]() | ![]() | ![]() | Análise Léxical |