Pergunta

Suponha que eu tenho uma expressão regular lex como

[aA][0-9]{2,2}[pP][sS][nN]? { return TOKEN; }

Se um usuário digita

A75PsN
A75PS

Ele irá corresponder

Mas se um usuário diz algo como

A75PKN

Eu gostaria que erro e dizer "Character K não reconhecido, esperando S"

O que estou fazendo agora é apenas escrevê-lo como

let [a-zA-Z]
num [0-9]

{let}{num}{2,2}{let}{2,3}

E, em seguida, essencialmente re-lexing a corda no Yacc para que eu possa ter condições de erro significativas

Como posso resolver isso?

A única coisa que posso pensar é usar grupos nomeados?

Foi útil?

Solução

Wow! esquema interessante.

Se você estiver indo para detectar que no analisador léxico, você teria que ter um catch-all regra que lida com 'qualquer seqüência de outra forma não reconhecido' e produz uma mensagem de erro.

A determinação de que era a K que causou o problema vai ser o inferno.

[^aA][0-9]{2,2}[pP][sS][nN]? { report_error(); return ERROR; }
[aA][0-9]{2,2}[^pP][sS][nN]? { report_error(); return ERROR; }
[aA][0-9]{2,2}[pP][^sS][nN]? { report_error(); return ERROR; }
[aA][0-9]{2,2}[pP][sS][^nN]  { report_error(); return ERROR; }

Observe a colocação dos sinais de intercalação, e a ausência do ponto de interrogação! Lidar com os não-dígitos, ou muitos dígitos, ou muito poucos dígitos - urgh

Geralmente, você seria melhor de reconhecer todos os 'identificadores' e, em seguida, validar quais são OK:

[a-zA-Z][0-9]{2,2}[a-zA-Z]{2,5} { return validate_id_string(); }

Escolha o seu veneno que você permitir que a rotina de validação; ele decide se o que foi digitado foi OK ou não, e seus controles valor de retorno o que o Lex regra retorna para a gramática. Esta é uma maneira de distinguir palavras-chave de identificadores também.

generalizar e simplificar a expressão regular para atender o que realmente se passa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top