![]() | ![]() | ![]() | 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 |