Qual é a diferença entre um token e um lexema?

86

Em Compiler Construction de Aho Ullman e Sethi, é dado que a string de entrada de caracteres do programa de origem são divididos em sequência de caracteres que têm um significado lógico, e são conhecidos como tokens e lexemas são sequências que compõem o token, então o que é a diferença básica?

user1707873
fonte

Respostas:

118

Usando " Compilers Principles, Techniques, & Tools, 2nd Ed. " (WorldCat) por Aho, Lam, Sethi e Ullman, também conhecido como o Livro do Dragão Roxo ,

Lexeme pg. 111

Um lexema é uma sequência de caracteres no programa de origem que corresponde ao padrão de um token e é identificado pelo analisador léxico como uma instância desse token.

Token pág. 111

Um token é um par que consiste em um nome de token e um valor de atributo opcional. O nome do token é um símbolo abstrato que representa um tipo de unidade lexical, por exemplo, uma palavra-chave específica ou sequência de caracteres de entrada denotando um identificador. Os nomes dos tokens são os símbolos de entrada que o analisador processa.

Padrão pág. 111

Um padrão é uma descrição da forma que os lexemas de um token podem assumir. No caso de uma palavra-chave como token, o padrão é apenas a sequência de caracteres que forma a palavra-chave. Para identificadores e alguns outros tokens, o padrão é uma estrutura mais complexa que é correspondida por muitas strings.

Figura 3.2: Exemplos de tokens pg.112

[Token]       [Informal Description]                  [Sample Lexemes]
if            characters i, f                         if
else          characters e, l, s, e                   else
comparison    < or > or <= or >= or == or !=          <=, !=
id            letter followed by letters and digits   pi, score, D2
number        any numeric constant                    3.14159, 0, 6.02e23
literal       anything but ", surrounded by "'s       "core dumped"

Para entender melhor essa relação com um lexer e um analisador, começaremos com o analisador e voltaremos para a entrada.

Para tornar mais fácil projetar um analisador, ele não funciona com a entrada diretamente, mas recebe uma lista de tokens gerados por um lexer. Olhando para a coluna de token na figura 3.2 podemos ver fichas tais como if, else, comparison, id, numbere literal; esses são nomes de tokens. Normalmente, com um lexer / analisador, um token é uma estrutura que contém não apenas o nome do token, mas os caracteres / símbolos que o compõem e a posição inicial e final da string de caracteres que o compõe, com o posição inicial e final sendo usada para relatório de erros, realce, etc.

Agora, o lexer recebe a entrada de caracteres / símbolos e, usando as regras do lexer, converte os caracteres / símbolos de entrada em tokens. Agora, as pessoas que trabalham com lexer / parser têm suas próprias palavras para as coisas que usam com frequência. O que você pensa como uma sequência de caracteres / símbolos que compõem um token é o que as pessoas que usam lexer / parsers chamam de lexema. Então, quando você vir o lexema, pense apenas em uma sequência de caracteres / símbolos representando um token. No exemplo de comparação, a sequência de caracteres / símbolos pode ser diferentes padrões, como <ou >ou elseou 3.14, etc.

Outra maneira de pensar na relação entre os dois é que um token é uma estrutura de programação usada pelo analisador que possui uma propriedade chamada lexema que contém o caractere / símbolos da entrada. Agora, se você olhar para a maioria das definições de token no código, pode não ver lexema como uma das propriedades do token. Isso ocorre porque um token provavelmente manterá a posição inicial e final dos caracteres / símbolos que representam o token e o lexema, a sequência de caracteres / símbolos pode ser derivada da posição inicial e final conforme necessário porque a entrada é estática.

Guy Coder
fonte
12
No uso do compilador coloquial, as pessoas tendem a usar os dois termos de maneira intercambiável. A distinção precisa é boa, se e quando você precisar.
Ira Baxter
Embora não seja uma definição puramente de ciência da computação, aqui está uma de processamento de linguagem natural que é relevante desde a Introdução à semântica lexical an individual entry in the lexicon
Guy Coder
Explicação absolutamente clara. É assim que as coisas devem ser explicadas no céu.
Timur Fayzrakhmanov
ótima explicação. Tenho mais uma dúvida, também li sobre o estágio de análise, o analisador pede tokens do analisador léxico, pois o analisador não pode validar tokens. você pode explicar tomando uma entrada simples no estágio do analisador e quando o analisador pede tokens do lexer.
Prasanna Sasne
@PrasannaSasne can you please explain by taking simple input at parser stage and when does parser asks for tokens from lexer.SO não é um site de discussão. Essa é uma nova pergunta e precisa ser feita como uma nova pergunta.
Guy Coder,
36

Quando um programa de origem é alimentado no analisador léxico, ele começa dividindo os caracteres em sequências de lexemas. Os lexemas são então usados ​​na construção de tokens, nos quais os lexemas são mapeados em tokens. Uma variável chamada myVar seria mapeada em um token informando < id , "num">, onde "num" deveria apontar para a localização da variável na tabela de símbolos.

Em poucas palavras:

  • Lexemes são as palavras derivadas do fluxo de entrada de caracteres.
  • Tokens são lexemas mapeados em um nome de token e um valor de atributo.


Um exemplo inclui:
x = a + b * 2
Que produz os lexemas: {x, =, a, +, b, *, 2}
Com tokens correspondentes: {< id , 0>, <=>, < id , 1 >, <+>, < id , 2>, <*>, < id , 3>}

William
fonte
2
É suposto ser <id, 3>? porque 2 não é um identificador
Aditya
mas onde diz que x é um identificador? isso significa que uma tabela de símbolos é uma tabela de 3 colunas com 'nome' = x, 'tipo' = 'identificador (id)', ponteiro = '0' como uma entrada particular? então ela deve ter alguma outra entrada como 'nome' = enquanto, 'tipo' = 'palavra-chave', ponteiro = '21 '??
8

a) Tokens são nomes simbólicos das entidades que compõem o texto do programa; por exemplo, if para a palavra-chave if e id para qualquer identificador. Eles constituem a saída do analisador léxico. 5

(b) Um padrão é uma regra que especifica quando uma sequência de caracteres da entrada constitui um token; por exemplo, a sequência i, f para o token if e qualquer sequência alfanumérica começando com uma letra para o id do token.

(c) Um lexema é uma sequência de caracteres da entrada que corresponde a um padrão (e, portanto, constitui uma instância de um token); por exemplo, if corresponde ao padrão de if e foo123bar corresponde ao padrão de id.

shasmoe
fonte
8

LEXEME - Sequência de caracteres combinados por PATTERN formando o TOKEN

PADRÃO - O conjunto de regras que define um TOKEN

TOKEN - A coleção significativa de caracteres sobre o conjunto de caracteres da linguagem de programação, por exemplo: ID, Constante, Palavras-chave, Operadores, Pontuação, Cadeia Literal

sravan kumar
fonte
7

Lexeme - um lexema é uma sequência de caracteres no programa de origem que corresponde ao padrão de um token e é identificado pelo analisador léxico como uma instância desse token.

Token - o token é um par que consiste em um nome de token e um valor de token opcional. O nome do token é uma categoria de uma unidade lexical. Nomes de token comuns são

  • identificadores: nomes que o programador escolhe
  • palavras-chave: nomes já na linguagem de programação
  • separadores (também conhecidos como pontuadores): caracteres de pontuação e delimitadores pareados
  • operadores: símbolos que operam em argumentos e produzem resultados
  • literais: literais numéricos, lógicos, textuais, de referência

Considere esta expressão na linguagem de programação C:

soma = 3 + 2;

Tokenizado e representado pela seguinte tabela:

 Lexeme        Token category
------------------------------
sum      |    Identifier
 =       |    Assignment operator
 3       |    Integer literal
 +       |    Addition operator
 2       |    Integer literal
 ;       |    End of statement
Rajat Bhatt
fonte
5

Vamos ver o funcionamento de um analisador léxico (também chamado de Scanner)

Vamos dar uma expressão de exemplo:

INPUT : cout << 3+2+3;

FORMATTING PERFORMED BY SCANNER :  {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;} 

mas não a saída real.

SCANNER SIMPLESMENTE PROCURA REPETIDAMENTE UM LEXEMA NO TEXTO DO PROGRAMA DE FONTE ATÉ QUE A ENTRADA SEJA ESGOTADA

Lexeme é uma substring de entrada que forma uma string de terminais válida presente na gramática. Cada lexema segue um padrão que é explicado no final (a parte que o leitor pode pular por último)

(A regra importante é procurar o prefixo mais longo possível formando uma string de terminais válida até que o próximo espaço em branco seja encontrado ... explicado abaixo)

LEXEMAS:

  1. cout
  2. <<

(embora "<" também seja uma string de terminal válida, mas a regra mencionada acima deve selecionar o padrão para o lexema "<<" a fim de gerar o token retornado pelo scanner)

  1. 3
  2. +
  3. 2
  4. ;

TOKENS: os tokens são retornados um de cada vez (pelo Scanner quando solicitado pelo Parser) cada vez que o Scanner encontra um lexema (válido). Scanner cria, se ainda não estiver presente, uma entrada de tabela de símbolos (tendo atributos: principalmente token-category e alguns outros) , quando encontra um lexema, a fim de gerar seu token

'#' denota uma entrada na tabela de símbolos. Eu apontei para o número do lexema na lista acima para facilitar o entendimento, mas tecnicamente deve ser o índice real de registro na tabela de símbolos.

Os tokens a seguir são retornados pelo scanner ao analisador na ordem especificada para o exemplo acima.

  1. <identificador, # 1>

  2. <Operador, # 2>

  3. <Literal, # 3>

  4. <Operador, # 4>

  5. <Literal, # 5>

  6. <Operador, # 4>

  7. <Literal, # 3>

  8. <Pontuador, # 6>

Como você pode ver a diferença, um token é um par diferente do lexema, que é uma substring de entrada.

E o primeiro elemento do par é o token-classe / categoria

As classes de token estão listadas abaixo:

  • PALAVRAS-CHAVE
  • IDENTIFICADORES
  • LITERAIS
  • PONTUADORES
  • OPERADORES
  • E mais uma coisa, Scanner detecta espaços em branco, os ignora e não forma nenhum token para um espaço em branco. Nem todos os delimitadores são espaços em branco, um espaço em branco é uma forma de delimitador usado por scanners para seu propósito. Tabulações, novas linhas, espaços, caracteres de escape na entrada são chamados coletivamente de delimitadores de espaço em branco. Alguns outros delimitadores são ';' ',' ':' etc, que são amplamente reconhecidos como lexemas que formam token.

    O número total de tokens retornados é 8 aqui, no entanto, apenas 6 entradas na tabela de símbolos são feitas para lexemas. Lexemes também são 8 no total (ver definição de lexemas)

    --- Você pode pular esta parte

    A ***pattern*** is a rule ( say, a regular expression ) that is used to check if a string-of-terminals is valid or not.

    If a substring of input composed only of grammar terminals is following the rule specified by any of the listed patterns , it is validated as a lexeme and selected pattern will identify the category of lexeme, else a lexical error is reported due to either (i) not following any of the rules or (ii) input consists of a bad terminal-character not present in grammar itself.

    for example :
    
    1. No Pattern Exists : In C++ , "99Id_Var" is grammar-supported string-of-terminals but is not recognised by any of patterns hence lexical error is reported .
    
    2. Bad Input Character : $,@,unicode characters may not be supported as a valid character in few programming languages.`
    
    Mayank narula
    fonte
    5

    Lexeme - um lexema é uma cadeia de caracteres que é a unidade sintática de nível mais baixo na linguagem de programação.

    Token - O token é uma categoria sintática que forma uma classe de lexemas que significa a qual classe o lexema pertence é uma palavra-chave ou identificador ou qualquer outra coisa. Uma das principais tarefas do analisador lexical é criar um par de lexemas e tokens, ou seja, coletar todos os personagens.

    Vejamos um exemplo: -

    if (y <= t)

    y = y-3;

    Lexeme Token

    se KEYWORD

    (PARÊNTESE ESQUERDA

    y IDENTIFICADOR

    <= COMPARAÇÃO

    t IDENTIFICADOR

    ) PARÊNTESE DIREITA

    y IDENTIFICADOR

    = ASSGNMENT

    y IDENTIFICADOR

    _ ARITMÁTICO

    3 INTEIRO

    ;                                    PONTO E VÍRGULA

    Relação entre Lexeme e Token

    Relação entre lexema e token

    coding_ninza
    fonte
    4

    Token: O tipo de (palavras-chave, identificador, caractere de pontuação, operadores de vários caracteres) é, simplesmente, um Token.

    Padrão: uma regra para a formação de token a partir de caracteres de entrada.

    Lexeme: É uma sequência de caracteres em SOURCE PROGRAM combinados por um padrão para um token. Basicamente, é um elemento do Token.

    mud1t
    fonte
    3

    Token: o token é uma sequência de caracteres que pode ser tratada como uma única entidade lógica. Os tokens típicos são:
    1) Identificadores
    2) palavras-chave
    3) operadores
    4) símbolos especiais
    5) constantes

    Padrão: um conjunto de strings na entrada para o qual o mesmo token é produzido como saída. Esse conjunto de strings é descrito por uma regra chamada padrão associada ao token.
    Lexeme: Um lexema é uma sequência de caracteres no programa de origem que corresponde ao padrão de um token.

    pradip
    fonte
    1

    Lexeme lexemes são referidos como sendo uma sequência de caracteres alfanuméricos () em um token.

    Símbolo Um token é uma sequência de caracteres que pode ser identificada como uma única entidade lógica. Normalmente, os tokens são palavras-chave, identificadores, constantes, strings, símbolos de pontuação, operadores. números.

    Padrão Um conjunto de strings descrito por uma regra chamada padrão. Um padrão explica o que pode ser um token e esses padrões são definidos por meio de expressões regulares, que são associadas ao token.

    user10715886
    fonte
    1

    Pesquisadores de ciência da computação, como os do Math, gostam de criar "novos" termos. As respostas acima são todas boas, mas, aparentemente, não há tanta necessidade de distinguir tokens e lexemas IMHO. Eles são como duas maneiras de representar a mesma coisa. Um lexema é concreto - aqui um conjunto de char; um token, por outro lado, é abstrato - geralmente referindo-se ao tipo de um lexema junto com seu valor semântico, se isso fizer sentido. Apenas meus dois centavos.

    zell
    fonte
    0

    O Lexical Analyzer pega uma sequência de caracteres, identifica um lexema que corresponde à expressão regular e o categoriza como token. Assim, um Lexeme é uma string combinada e um nome de Token é a categoria desse lexema.

    Por exemplo, considere a expressão regular abaixo para um identificador com a entrada "int foo, bar;"

    letra (letra | dígito | _) *

    Aqui, fooe barcorrespondem à expressão regular, portanto, ambos são lexemas, mas são categorizados como um token, IDou seja, identificador.

    Observe também que a próxima fase, isto é, o analisador de sintaxe não precisa saber sobre o lexema, mas um token.

    vikram barandwal
    fonte
    -2

    Lexeme é basicamente a unidade de um token e é basicamente uma sequência de caracteres que corresponde ao token e ajuda a quebrar o código-fonte em tokens.

    Por exemplo: Se a fonte for x=b, então os lexemas seria x, =, be os tokens seria <id, 0>, <=>, <id, 1>.

    Subhasmit halder
    fonte
    Uma resposta deve ser mais específica. Um exemplo pode ser útil.
    Zverev Evgeniy