Anda di halaman 1dari 12

http://pt.stackoverflow.

com/questions/113578/o-que-%C3%A9-analise-l%C3%A9xica/114050

O que analise lxica?


Eu estava dando uma olhada no cdigo-fonte de uma library conhecida do php,
chamada Twig (trata-se de um template engine, com sintaxe prpria), e me
deparei com classes, interfaces e mtodos, como Lexical, Lex e
LexInterface.
Dei uma pesquisada e percebi que se tratava do termo anlise lxica.
Apesar de ter entendido algumas coisas, fiquei confuso em outras.
Por exemplo, estou acostumado a ver o termo Parser ou Parsing, quando se
trata em transformao de um determinado dado em outro dado.
votar a favor
26 votar contra
favorita
4

O que seria a Anlise Lxica?


Anlise Lxica e Parsing/Parser se trata das mesmas coisas, ou na verdade
so coisas diferentes?
Desculpem se estou confuso na pergunta, mas creio que a comunidade me ajudar
com uma boa e esclarecedora resposta.
terminologia parser analise-lxica
perguntada 16/02 s 17:36
compartilharmelhorar esta pergunta

Wallace Maxters
26,6mil429124

Talvez responda pt.stackoverflow.com/a/104818/91, mais ou menos


no meio da resposta tem uma explicao sobre anlise lxica.
rray 16/02 s 17:40
@rray j um bom caminho. Eu no saberia pesquisar (um termo
especfico) para descobrir como chegar nessa resposta. Wallace
Maxters 16/02 s 17:45
1
Voc escuta bastante esse termo em autmatos. rray 16/02 s
17:47
1

Voc no consegue "proteger" sua pergunta de votos contras, a


proteo apenas evita que novos usurios respondam ela, no faz
muito sentido proteger sua pergunta no momento ;-) Math 18/02
s 12:46
1
Eu sei @Math. Eu confesso que protejo algumas s para poder usar
a funcionalidade, rsrsrsrs. Wallace Maxters 18/02 s 13:28
mostrar mais 3 comentrios

6 Respostas
ativas mais antigas votos

votar a
favor
16
votar Anlise lxica o processo realizado sobre um texto, digamos um programa de computador ou ento um
contra este em lexemes e os converte para uma sequncia de tokens, os quais so usados para alimentar um
aceitos geralmente chamado de lexer, scanner ou tokenizer.
+100

Definio

tokens / lexemes

Lexemes so unidades sintticas relevantes do contexto do lexer, por exemplo para um lexer voltado a um
poderiam ser: 1, "ol", for, ==, variableName, function.

Um token uma estrutura que categoriza um lexeme, ele contm um nome abstrato que representa o gru
no seja nico. Exemplo de alguns tokens (o token representado no formato < token, valor-opcional> e
<
<
<
<
<
<

digit, 1 > # qualquer valor numrico


literal, "ol" > # valores contidos entre aspas duplas
for > # os caracteres f,o,r
comparison, == > # os smbolos <, >, <=, >=, == e !=
id, variableName > # sequncia de letras que representa uma varivel
function > # as letras f,u,n,c,t,i,o,n

diferena entre parsing

Lexers e parsers esto intimamente ligados contudo so conceitos distintos. O lexer especializado em e

em estruturas com "significado", no caso os tokens. J o parser tem a funo de analisar a estrutura sint
determinada linguagem de programao a expresso "ol" 1 == "outroliteral" sintaticame
as estruturas produzidas pelo lexer so o que parser usa como fonte para realizar o parsing, ou seja, o pa
impede de construir um parser que faa a anlise sinttica em cima de texto puro, contudo a separao d

1. Simplificao do design. Um parser que tambm realize o trabalho de um lexer significantemen


2. Otimizao. Separando as duas tarefas (lexing e parsing) voc tem mais liberdade para aplicar t

um lexer na prtica

A teoria essencial, contudo nada melhor que cdigo real para ajudar na compreenso. Aqui eu mostro u
subconjunto de CSS, mais especificamente ele lida com este exemplo:
h1 {
color: red;
font-size: 30px;
}
body {
background-color: yellow;
}
div {
margin: 10px;
padding: 10px;
}

O cdigo pode ser executado e ir mostrar a lista de tokens gerados aps processar nosso CSS alvo:
// nosso CSS
var css = "h1 { \n\
color: red; \n\
font-size: 30px; \n\
} \n\
\n\
body { \n\
background-color: yellow; \n\
} \n\
\n\
div { \n\
margin: 10px; \n\
padding: 10px; \n\
} \n\
";

/**
* Lista que define nossos tokens e as respectivas expresses regulares que os encon
*/
var TOKENS = [
{name: 'EMPTY', regex: /^(\s+)/ },
{name: 'RULE_SET_START', regex: /^({)/ },
{name: 'RULE_SET_END', regex: /^(})/ },
{name: 'RULE_DEFINITION', regex: /^(:)/ },
{name: 'RULE_END', regex: /^(;)/ },
{name: 'SELECTOR', regex: /^([a-zA-Z]+[a-zA-Z0-9]*)(?=\s*{)/ },
{name: 'RULE', regex: /^([a-z][-a-z]+)(?=\s*:)/ },
{name: 'RULE_VALUE', regex: /^(\w+)(?=\s*(;|}))/ }
];

var text = css;


var outputTokenList = [];
while(text !== '') { // enquanto existir texto a ser consumido
var hasMatch = false;

/**
* Iteramos sobre toda a lista de TOKENS at encontrarmos algum cujo padro
* Quando ocorre um "match" ns adicionamos o lexeme com seu respectivo tok
* Caso nenhum padro bata com o texto uma exceo lanada imprimindo a l
*
*/
for (var i=0; i<TOKENS.length; i++) {
var obj = TOKENS[i];
var tokenName = obj.name;
var tokenRegex = obj.regex;
var matched = text.match(tokenRegex);
if (!matched) {
continue;
}
hasMatch = true;
var lexeme = matched[1];
// removemos do texto o lexeme encontrado
// para que outro possa ser considerados
// na prxima iterao
text = text.substring(lexeme.length);

if (tokenName in {'SELECTOR': 1, 'RULE': 1, 'RULE_VALUE': 1}) {


// adicionamos tanto o nome do token quanto o lexeme
outputTokenList.push([tokenName, lexeme]);
}
else if (tokenName in {'EMPTY': 1}) {
// discard, no nos importamos com espaos e quebras de lin
}
else {
// nestes casos o relacionamento entre o nome do token
// e o lexeme 1<->1 ento no precisamos adicionar o lexe
outputTokenList.push([tokenName]);
}
};

break;

if (!hasMatch) {
throw 'Invalid pattern at:\n' + (text.substring(0, text.indexOf('\n
break;
}

outputTokenList.forEach(function(token) {
document.write('< ' + token[0]);
if (token.length > 1) {
document.write(' , ' + token[1]);
}
document.write(' ><br>');
});

Expand snippet

No vou entrar em explicaes sobre as implementaes de


lexers pois este um assunto extenso e no diretamente
relacionado a pergunta, ento note que esta apenas uma
ilustrao do possvel funcionamento de um lexer, l um texto
alvo e gera tokens como sada, o cdigo no nem eficiente nem
robusto.

compartilharmelhorar esta
resposta

editada 22/02
s 16:47

respondida 20/02
s 2:01
BrunoRB
3.142217
Gostei! (+1) e
vou roubar o teu
exemplo na
minha resposta :)
JJoao 25/02 s
22:49
comentar

O que seria a Anlise Lxica?


a anlise de linhas de caracteres para se criar smbolos que facilitem a compreenso
do que est escrito ali.
Anlise Lxica e Parsing/Parser se trata das mesmas coisas, ou na
verdade so coisas diferentes?
So complementares.
A primeira etapa a gerao de smbolos (tokens), chamada de anlise lxica, pelo
votar a favor qual o fluxo de caracteres de entrada dividido em smbolos significativos definidos
por uma gramtica de expresses regulares.
9 votar
contra
A segunda etapa a anlise sinttica, que a verificao de que os tokens formam
uma expresso permitida.
A fase final a anlise semntica, que elabora as implicaes da expresso validada e
toma a ao apropriada.
respondida 19/02 s 11:32
compartilharmelhorar esta resposta

Rodrigo Guiotti
1.841116

"Primeira etapa, segunda etapa, fase final" etapas/fases do que?


imagino que sejam o front end de um compilador, contudo faltou
especificar isto no texto. BrunoRB 20/02 s 18:55
Etapas de um parser (analisador? desconheo uma boa traduo).
Pode realmente ser de um compilador, j que ele precisa fazer
isso, mas pode ser de um parser que esteja analisando uma
comunicao XML ou JSON, por exemplo. Rodrigo Guiotti
22/02 s 11:07
comentar
Anlise lxica e sinttica (parsing) so de fato coisas bem parecidas, tendo em vista que
os algoritmos que trabalham nessas duas frentes operam de forma similar: a entrada
processada por ambos similar e os resultados que apresentam tambm.
Conforme mencionaram nos comentrios da pergunta, de fato se houve muito essa
expresso quando se estuda autmatos justamente porque analisadores lxicos lidam
apenas com linguagens regulares. Na prtica, um analisador lxico atua como um
reconhecedor de tokens. Isto , dada a gramtica de uma linguagem regular qualquer, um
analisador lxico capaz de determinar se dada sequncia de caracteres faz parte dessa
linguagem ou no. Da vem as famosas expresses regulares.
Diferentemente, parsers atuam com um nvel mais complexo de linguagens pois lidam
com linguagens livres de contexto. Tambm na prtica, parsers costumam processar uma
sequncia de tokens (geralmente reconhecidos por lexers) e determinam se tais tokens
satisfazem as estruturas definidas na gramtica dessa linguagem.

votar a
favor 8
votar
contra

Portanto, a anlise lxica consiste em validar tokens levando em considerao as regras


de formao de uma linguagem regular, se essa linguagem no mais regular, ento
trata-se de um parser. No caso do Twig, por se tratar de uma engine de templates,
acredito que a anlise lxica ocorra no reconhecimento dos marcadores especiais como
{{, else, {% etc.

Estou atualizando minha resposta por acreditar que ela no foi ampla o suficiente e
tambm por achar que as outras respostas apresentadas ou foram genricas demais ou
atrelaram muito lexers a parsers.
Primeiro as semelhanas fundamentais entre lexers e parsers:
1. Ambos tem como entrada smbolos de algum alfabeto. Geralmente os smbolos
de um lexer so caracteres ASCII ou Unicode enquanto que parsers processam
tokens (smbolos terminais da gramtica que esto validando).
2. Eles analisam esses smbolos associando-os a uma gramtica pra reconhec-los
como membros de uma linguagem. Conforme expliquei acima, lexers validam
apenas linguagens regulares enquanto que parsers operam em linguagens livres
de contexto. Nveis 3 e 2 na hierarquia de Chomsky, respectivamente.
3. Ambos produzem como sada sentenas da linguagem que esto avaliando.
Lexers distinguem tokens de uma sequncia de caracteres dada como entrada,

enquanto que parsers geram rvores sintticas.


Com relao ao ltimo ponto, ainda que ambos sejam complementares na grande maioria
dos casos, isso no significa que um parser sempre haver de receber sua entrada
tokenizada de um lexer. Sendo um parser capaz de gerar mltiplas sentenas de uma
linguagem L1 qualquer, podemos obter uma linguagem L2 cujos tokens sejam sentenas
de L1. Sendo assim, parsers tambm podem ser tokenizadores de outros parsers.
Em processamento de linguagem natural, parsers obtm sua entrada tokenizada a partir
de uma srie de etapas que podem envolver edio manual, anlise estatstica e machine
learning.
Portanto, a diferena fundamental entre ambos como eu j expliquei acima: o nvel da
linguagem em que operam e consequentemente a complexidade necessria para operar
sob este nvel. Enquanto que pra linguagens regulares autmatos de estado finito so
suficientes, linguagens livres de contexto requerem mecanismos mais complexos como
autmatos de pilha e toda a enorme variao de parsers existentes (bottom-up, top-down,
tabulares etc).
respondida 18/02 s 20:25
compartilharmelhorar esta resposta editada 21/02 s 23:32

Roney Gomes
36616

Tem afirmaes erradas a Roney: " a anlise lxica consiste em validar


tokens", a anlise lxica produz tokens e no valida eles, pois tokens
no existem antes de o lexer os gerar, a validao ocorre sobre os
lexemes. BrunoRB 21/02 s 22:59
@BrunoRB lexers no so mecanismos geradores, portanto no
produzem tokens. Eles validam a entrada como tokens ou no. Voc
pode entender como produo por ainda estar amarrado ao seu
emprego no front-end de um compilador, mas so em suma
reconhecedores de sua entrada tendo em vista visto uma gramtica
regular referencial. Distinguir numa string de entrada quais so os
tokens da linguagem referncia no implica que tais tokens so
produzidos. Deixei explcito na resposta que tokens so nada mais que
os smbolos atmicos de uma LR, portanto no h porque produzir o
que j existe. Roney Gomes 21/02 s 23:13
... the main task of the lexical analyzer is to
read the input characters of the source
program, group them into lexemes, and produce
as output a sequence of tokens for each lexeme
in the source program Compilers: Principles, Techniques, and
Tools. BrunoRB 21/02 s 23:17
@BrunoRB sim cara, uma definio entre tantas. A distino entre
tokens e lexemas so terminologias criadas pra melhor apresentar os
conceitos interessantes sua aplicao em compiladores. Eu utilizo
uma definio distinta em que o termo token empregado como
"constituinte atmico de uma linguagem". Contanto que as ideias
apresentadas sejam coerentes com a definio, no h porque debater.
Eu poderia cham-los de bolinha, se fosse interessante. Acredito que
fui coerente com a definio que apresentei e por isso no vejo sentido
em extender esse no dilogo. Roney Gomes 21/02 s 23:28
1
@BrunoRB com teus comentrios notei uma possvel contradio na
minha resposta e a editei pra que fique mais explcito o meu
entendimento do assunto. Obrigado. Roney Gomes 21/02 s 23:36
votar a
favor 5
votar
contra

comentar
Um interpretador/compilador no entende "texto grosso" diretamente, ele precisa dos
dados bem organizados e definidos.
Por exemplo, vamos supor que nosso interpretador precise interpretar essa simples
soma:
42 + 42

Como resolvemos isso? a que entra o papel do analisador lxico.


O programador que criou nosso interpretador imaginrio definiu que um nmero o
conjunto de 1 dgito seguido de outros dgitos e que soma simplesmente o smbolo '+'.

[0-9]+ returns NUMBER;


"+"
returns PLUS;
" "
;

E agora? Bom, vamos analisar o que acontece quando ele analisa a entrada, sendo o
ponto final o caractere que ele est analisando:
1) . 42 (Nosso analisador contm o nmero 4 no buffer, ele sabe que pela definio, um
nmero 1 dgito seguido de mais dgitos.)
2) 4 . 2 (At agora, ele possui 4 como nmero e continua, armazenando 2 no buffer.)
3) 42 . ( o fim do nmero, nosso interpretador retorna NUMBER. Encontramos um
espao em branco, que pela definio, no retorna nada.)
Por enquanto, sabemos isso:
<NUMBER, 42> . + 42

O analisador est sobre o '+', ele sabe que pela definio um PLUS:
<NUMBER, 42> <PLUS, '+'> . 42

E o mesmo processo sobre o 42:


<NUMBER, 42> <PLUS, '+'> <NUMBER, 42>

A anlise foi concluda, e agora? Nosso interpretador pode interpretar esses dados de
forma consistente. Vamos supor que nosso interpretador use uma gramtica bem
simples e restritiva para somas:
sum -> NUMBER PLUS NUMBER

Ele pode utilizar os tokens de sada do analisador lxico e se focar somente no parsing.
Como a sada consiste de NUMBER PLUS NUMBER, se enquadra como uma soma
vlida.
respondida 24/02 s 17:02
compartilharmelhorar esta resposta editada 24/02 s 17:09

dxhj
516213

comentar
As respostas apresentadas so muito boas, e j abordaram toda a parte tcnica do
assunto. Portanto, apenas complementando a informao, segue uma explicao
focada apenas na etimologia das palavras.
votar a favor 4
votar contra

Anlise Lxica
Refere-se ao vocabulrio da linguagem (palavras). De uma forma simples, uma

anlise de dicionrio e verifica a existncia dos termos/vocbulos dentro da


linguagem.
Por exemplo "carnaval", "ovo", "bola" fazem parte do lxico da lngua portuguesa.
J as palavras "party", "egg", "ball" fazem parte do lxico da lngua inglesa. A
anlise lxica no se preocupa com ordem ou sentido dos termos, mas somente com
os termos em si.
Voc pode ver um exemplo tcnico aqui.

Anlise Sinttica
Refere-se as regras gramaticais da linguagem, ou seja, trata-se de como podemos
organizar os termos da linguagem para criar um sentido. Pode encarar como a forma
em que um comando deve ser estruturado para executar uma ao, ou as regras para
a formao de uma frase.
Exemplo tcnico aqui.

Anlise Semntica
Aqui estamos falando do sentido/significado empregado na frase/comando. Por
exemplo, podemos utilizar a frase Me inclui fora dessa, onde as palavras e
a sintaxe esto corretas mas semanticamente no.
Exemplo tcnico aqui.

Essas definies fazem parte da lingustica como um todo e so utilizadas como


uma forma de organizar e facilitar o entendimento de como um cdigo/processo se
prope a trabalhar.
Escolhi no utilizar uma abordagem tcnica e passar exemplos da lngua
portuguesa, pois eles so igualmente vlidos quando voc pensa nas linguagens de
programao e tornam o entendimento dos termos mais simples.

compartilharmelhorar esta resposta

editada 23/02 s
19:18

respondida 22/02 s
17:45
Bruno Oliveira
1407

(+1) sujesto: junta a pragmtica! JJoao


25/02 s 22:51

comentar
votar a J se disse tudo; no entanto eu gosto de processadores de linguagens, e no resisto a pr aqui um exempl
favor
4
Enunciado: dado uma CSS (simplificada, vou tomar como exemplo o caso apresentado por @BrunoRP)
votar

contra propriedades tem cada tag.

Gramtica tradutora: gramtica + aes semnticas


Analisador sintatico=parser (yacc)
%{
#include <stdio.h>
%}
%union {char *s; int i;}
%token <s> ID STR MEA
%type <i> props
%%
css

:
| css bloco
;
bloco: ID '{' props '}'
;
props:
| props prop
;
prop : ID ':' v ';'
v
: ID | STR | MEA
%%
#include "lex.yy.c"

// bloco*
{ printf("%s - %d\n",$1,$3);}
{ $$ = 0
;}
{ $$ = $1+1 ;}

// prop*
// contar as prop

;
;

// propriedade
// valor

yyerror(char *s){fprintf(stderr,"ERRO (linha %d):'%s'\n-%s",yylineno, yytext,s);}


int main() { yyparse(); return 0; }

Analidasor lxico (flex)


%option yylineno
%option noyywrap
%%
[ \n\t]+
#.*

{
{

[{}:;]

{ return yytext[0];} // caracteres especiais

} // ignorar espaos
} // ignorar comentrios

[a-zA-Z][-a-zA-Z0-9]* { yylval.s=strdup(yytext);
\"[^\"]*\"
{ yylval.s=strdup(yytext);
[0-9]+(px|pt|mm)
{ yylval.s=strdup(yytext);
.

return ID; }
return STR; }
return MEA; }

{fprintf(stderr,"%d: Erro - invalid character '%c'\n",yylineno,yytext[0]);}

%%

O que a anlise lxica:


1.
2.
3.
4.

saltar os espaos e comentrios


retornar os cdigos das palavras reservadas e carateres especias
agrupar os caracter que formam os ID, etc; retornar o seu cdigo e valor
tratar dos erros lxicos

Compilando e testando:
$
$
$
$

flex proc.l
yacc proc.y
cc -o proc y.tab.c
proc < ex.css
##ex.css o exemplo de css do @BrunoRP

h1 - 2
body - 1
div - 2

Anda mungkin juga menyukai