Skip to content

Commit 40925e6

Browse files
committed
improve readability and maintainability of the hand made lexer
1 parent aa53622 commit 40925e6

1 file changed

Lines changed: 149 additions & 152 deletions

File tree

lex.c

Lines changed: 149 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -559,11 +559,13 @@ int is_allowed_identifier(Token* tk)
559559
break;
560560
}
561561
}
562-
563-
if (simbol) // se contem algo a mais que letras ou numeros, nao eh identificador valido
562+
563+
// se contem algo a mais que letras ou numeros, nao eh identificador valido
564+
if (simbol)
564565
return 0;
565566

566-
if (is_reserverd_word(tk)) // palavra reservada nao pode ser identificador
567+
// palavra reservada nao pode ser identificador
568+
if ( is_reserverd_word(tk) )
567569
return 0;
568570

569571
return 1;
@@ -573,8 +575,6 @@ ListToken* tokeniza(FILE* arquivo)
573575
{
574576
int linha = 1; // contador para linha corrente do arquivo
575577
int coluna = 0; // contador para coluna corrente (em determinada linha do arquivo)
576-
int erro = 0; // flag de erro, encerra a analise
577-
int fim = 0; // flag para indicar o termino da analise
578578

579579
char c = '\0'; // usado para leitura de um caraceter
580580
char* tok; // usado para a leitura de uma string que representa um token
@@ -583,110 +583,66 @@ ListToken* tokeniza(FILE* arquivo)
583583

584584
tok = (char*) xmalloc( sizeof(char) * MAX_TOKEN_SIZE );
585585

586-
while (1)
587-
{
588-
A: // Label para parte A do automato
586+
// nota: este codigo foi elaborado a partir de um automato finito (DFA)
587+
// que foi desenhado manualmente, em algumas folhas de papel, por mim.
589588

590-
c = fgetc(arquivo);
589+
start_state: // label para a parte inicial do automato
591590

592-
A_1: // parte A sem captura de novo char
593-
594-
copy(tok, "");
591+
c = fgetc(arquivo);
595592

596-
if (c == EOF)
597-
goto encerrar;
593+
start_after_getc_state: // estado apos inicio, pula captura de novo char
594+
595+
copy(tok, "");
598596

599-
if (isspace(c)) {
600-
if (c == '\n') {
601-
coluna = 0;
602-
linha++;
603-
}
604-
else {
605-
coluna++;
606-
}
597+
if (c == EOF)
598+
goto end_state;
607599

608-
goto A;
600+
if (isspace(c)) {
601+
if (c == '\n') {
602+
coluna = 0;
603+
linha++;
609604
}
610-
611-
if (c == '/') {
612-
comentarios: // Label para inicio da parte que trata os comentarios
613-
605+
else {
614606
coluna++;
615-
c = fgetc(arquivo);
616-
617-
// line comment
618-
if (c == '/') {
619-
coluna++;
607+
}
620608

621-
while (c != '\n')
622-
{
623-
c = fgetc(arquivo);
624-
coluna++;
609+
goto start_state;
610+
}
625611

626-
if (c == EOF)
627-
goto encerrar;
628-
}
612+
if (c == '/') {
613+
comments_state: // label para inicio da parte que trata os comentarios
629614

630-
coluna = 0;
631-
linha++;
615+
coluna++;
616+
c = fgetc(arquivo);
632617

633-
goto A;
634-
}
635-
else if (c == '*') { // multi-line
636-
coluna++;
618+
if (c == '/') { // single line comment
619+
coluna++;
637620

621+
while (c != '\n')
622+
{
638623
c = fgetc(arquivo);
624+
coluna++;
639625

640-
while (1)
641-
{
642-
M: // Label para a parte de comentario de multiplas linhas
643-
644-
if (c == EOF)
645-
goto encerrar;
646-
647-
if (c == '\n') {
648-
coluna = 0;
649-
linha++;
650-
}
651-
else
652-
coluna++;
653-
654-
if (c == '*') {
655-
c = fgetc(arquivo);
656-
657-
if (c == '/') {
658-
coluna++;
659-
break;
660-
}
661-
else
662-
goto M;
663-
}
626+
if (c == EOF)
627+
goto end_state;
628+
}
664629

665-
c = fgetc(arquivo);
666-
}
630+
coluna = 0;
631+
linha++;
667632

668-
goto A;
669-
}
670-
else {
671-
// recognize SYM_SLASH
672-
insert_token_of_char(tokens, '/', linha, coluna);
673-
goto A_1;
674-
}
633+
goto start_state;
675634
}
676-
else if (c == '"') {
635+
else if (c == '*') { // multi-line comment
677636
coluna++;
678637

679-
anexa(tok, c);
680-
681638
c = fgetc(arquivo);
682639

683640
while (1)
684641
{
685-
// S: captura de strings literais
686-
if (c == EOF) {
687-
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
688-
goto encerrar;
689-
}
642+
multiline_comments_state: // label for multi-line comments part
643+
644+
if (c == EOF)
645+
goto end_state;
690646

691647
if (c == '\n') {
692648
coluna = 0;
@@ -695,94 +651,135 @@ ListToken* tokeniza(FILE* arquivo)
695651
else
696652
coluna++;
697653

698-
anexa(tok, c);
654+
if (c == '*') {
655+
c = fgetc(arquivo);
699656

700-
if (c == '"') {
701-
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
702-
break;
657+
if (c == '/') {
658+
coluna++;
659+
break;
660+
}
661+
else
662+
goto multiline_comments_state;
703663
}
704664

705665
c = fgetc(arquivo);
706666
}
707667

708-
goto A;
668+
goto start_state;
669+
}
670+
else {
671+
// recognize SYM_SLASH
672+
insert_token_of_char(tokens, '/', linha, coluna);
673+
goto start_after_getc_state;
709674
}
675+
}
676+
else if (c == '"') {
677+
coluna++;
710678

711-
// B: a parte B do automato
679+
anexa(tok, c);
712680

713-
if (is_symbol(c)) {
714-
// TODO: capture symbols larger than 1 char
715-
symbols_capture:
716-
coluna++;
717-
insert_token_of_char(tokens, c, linha, coluna);
718-
goto A;
719-
}
681+
c = fgetc(arquivo);
720682

721-
if ( !isalnum(c) && c != '_' ) {
722-
show_error_lexical(MSG_ERROR_LEX_INVALID_CHAR, linha, coluna);
723-
goto encerrar;;
724-
}
683+
while (1)
684+
{
685+
// S: captura de strings literais
686+
if (c == EOF) {
687+
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
688+
goto end_state;
689+
}
690+
691+
if (c == '\n') {
692+
coluna = 0;
693+
linha++;
694+
}
695+
else
696+
coluna++;
725697

726-
if (isalnum(c) || c == '_') {
727-
coluna++;
728698
anexa(tok, c);
729699

730-
while (1)
731-
{
732-
P: // Label para parte P do automato
700+
if (c == '"') {
701+
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
702+
break;
703+
}
733704

734-
c = fgetc(arquivo);
705+
c = fgetc(arquivo);
706+
}
735707

736-
if (isspace(c)) {
737-
if (c == '\n') {
738-
coluna = 0;
739-
linha++;
740-
}
741-
else {
742-
coluna++;
743-
}
744-
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
745-
break;
746-
}
747-
else if (c == '/') {
748-
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
749-
goto comentarios;
750-
}
751-
else if (is_symbol(c)) {
752-
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
753-
goto symbols_capture;
754-
}
755-
else if(isalnum(c) || c == '_') {
756-
coluna++;
757-
anexa(tok, c);
758-
759-
// verificar tamanho maximo de palavra
760-
if (len(tok) > MAX_TOKEN_SIZE) {
761-
show_error_lexical(MSG_ERROR_LEX_TOKEN_SIZE_MAXED,
762-
linha,
763-
coluna - len(tok) );
764-
goto encerrar;
765-
}
708+
goto start_state;
709+
}
766710

767-
goto P;
768-
}
769-
else if (c == EOF) {
770-
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
771-
goto encerrar;
772-
}
773-
else {
774-
show_error_lexical(MSG_ERROR_LEX_INVALID_CHAR, linha, coluna);
775-
goto encerrar;
776-
}
711+
// B: a parte B do automato (na folha de papel)
712+
713+
if (is_symbol(c)) {
714+
// TODO: capture symbols larger than 1 char
715+
symbols_capture_state:
716+
coluna++;
717+
insert_token_of_char(tokens, c, linha, coluna);
718+
goto start_state;
719+
}
720+
721+
if ( !isalnum(c) && c != '_' ) {
722+
show_error_lexical(MSG_ERROR_LEX_INVALID_CHAR, linha, coluna);
723+
goto end_state;
724+
}
725+
726+
if (isalnum(c) || c == '_') {
727+
coluna++;
728+
anexa(tok, c);
729+
730+
expecting_identifiers_state:
731+
732+
c = fgetc(arquivo);
733+
734+
if (isspace(c)) {
735+
if (c == '\n') {
736+
coluna = 0;
737+
linha++;
777738
}
739+
else {
740+
coluna++;
741+
}
742+
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
743+
goto start_state;
744+
}
745+
else if (c == '/') {
746+
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
747+
goto comments_state;
778748
}
749+
else if (is_symbol(c)) {
750+
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
751+
goto symbols_capture_state;
752+
}
753+
else if(isalnum(c) || c == '_') {
754+
coluna++;
755+
anexa(tok, c);
779756

780-
if (erro || fim) {
781-
encerrar: // Label para o encerramento
782-
break;
757+
// verificar tamanho maximo de palavra
758+
if (len(tok) > MAX_TOKEN_SIZE) {
759+
show_error_lexical(MSG_ERROR_LEX_TOKEN_SIZE_MAXED,
760+
linha,
761+
coluna - len(tok) );
762+
goto end_state;
763+
}
764+
765+
goto expecting_identifiers_state;
766+
}
767+
else if (c == EOF) {
768+
insert_token_of_string(tokens, tok, linha, coluna - len(tok));
769+
goto end_state;
770+
}
771+
else {
772+
show_error_lexical(MSG_ERROR_LEX_INVALID_CHAR, linha, coluna);
773+
goto end_state;
783774
}
775+
776+
goto expecting_identifiers_state;
784777
}
785778

779+
goto start_state;
780+
781+
end_state: // label para o estado de encerramento do lexer
782+
786783
//show_token_list(tokens);
787784

788785
free(tok);

0 commit comments

Comments
 (0)