Difference between revisions of "The Flex Lexical Analyzer/Exercise 5 - Removing the actions from a Flex specification"

From Wiki**3

< The Flex Lexical Analyzer
(New page: == The Problem (in Portuguese) == Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação Flex e que a copie para a saída sem as acções assoc...)
 
 
(3 intermediate revisions by the same user not shown)
Line 8: Line 8:
  
 
Exemplo:
 
Exemplo:
<text>
+
<source lang="text">
 
%option stack noyywrap yylineno 8bit debug
 
%option stack noyywrap yylineno 8bit debug
 
%option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp"
 
%option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp"
Line 24: Line 24:
 
                       }
 
                       }
 
%%
 
%%
</text>
+
</source>
  
 
== The Solution ==
 
== The Solution ==
  
<text>
+
[EXPLANATION COMING SOON]
 +
 
 +
<source lang="text">
 
%option 8bit noyywrap yylineno stack debug
 
%option 8bit noyywrap yylineno stack debug
 
%{
 
%{
Line 91: Line 93:
 
   return yylex();
 
   return yylex();
 
}
 
}
</text>
+
</source>
  
[[category:Compilers]]
+
[[category:Compiladores|Flex Lexical Analyzer]]
[[category:Teaching]]
+
[[category:Ensino]]

Latest revision as of 13:46, 4 March 2019

The Problem (in Portuguese)

Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação Flex e que a copie para a saída sem as acções associadas às regras. Codifique todas as rotinas auxiliares.

Uma especificação Flex, está dividida em três zonas separadas por %% (declarações, regras, código). As zonas de declarações e código devem ser copiadas integralmente para a saída.

Considere que cada regra Flex começa com um padrão (possivelmente precedido por uma lista de condições entre < e >), seguido por espaços brancos ou tabulações e por uma acção. Cada acção (constituída por código C/C++ arbitrário) pode ser escrita ao longo de várias linhas se estiver delimitada por {}, caso contrário, termina no final da linha. Cada padrão é composto por símbolos do alfabeto da linguagem e por vários operadores. Espaços que apareçam nos padrões devem ser precedidos por \ ou aparecer entre aspas (").

Exemplo:

%option stack noyywrap yylineno 8bit debug
%option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp"
%{
#include <string>
#include <cdk/nodes/Node.h>
#include "Scanner.h"
#include "Parser.tab.h"
%}
%%
" "				return T_SPACE;
[A-Za-z][A-Za-z0-9_]*  {
                           yylval.s = new std::string(yytext);
                           return T_VARIABLE;
                       }
%%

The Solution

[EXPLANATION COMING SOON]

%option 8bit noyywrap yylineno stack debug
%{
#include <iostream>
inline void yyerror(const char *msg) {
  std::cerr << "Error at " << yylineno << ": " << msg << std::endl;
}
%}
%x X_RULES X_RANGE X_STRING X_CODE1 X_CODE2 X_STRIGN X_CHARIGN X_COMMENT
%%

^"%%"                                   ECHO; yy_push_state(X_RULES);

<X_RULES>^[ \t]+.*\n                    ECHO;  //lines to be ignored

<X_RULES>"["                            ECHO; yy_push_state(X_RANGE);
<X_RANGE>"]"                            ECHO; yy_pop_state();
<X_RANGE>"\\["                          ECHO;
<X_RANGE>"\\]"                          ECHO;
<X_RANGE>.                              ECHO;
<X_RANGE>\n                             yyerror("newline in range");

<X_RULES>\\\"                           ECHO; //avoid erroneous transition
<X_RULES>\"                             ECHO; yy_push_state(X_STRING);
<X_STRING>\"                            ECHO; yy_pop_state();
<X_STRING>\\\"                          ECHO;
<X_STRING>.                             ECHO;
<X_STRING>\n                            yyerror("newline in string");

<X_RULES>[ \t]+                         yy_push_state(X_CODE1);
<X_CODE1>\n                             ECHO; yy_pop_state();
<X_CODE1>"{"                            yy_push_state(X_CODE2);
<X_CODE2>"}"                            yy_pop_state();

<X_CODE1,X_CODE2>\'                     yy_push_state(X_CHARIGN);
<X_CHARIGN>\'                           yy_pop_state();
<X_CHARIGN>\\\'                         ;
<X_CHARIGN>.                            ;
<X_CHARIGN>\n                           yyerror("newline in char");

<X_CODE1,X_CODE2>\"                     yy_push_state(X_STRIGN);
<X_STRIGN>\\\"                          ;
<X_STRIGN>\"                            yy_pop_state();
<X_STRIGN>.                             ;
<X_STRIGN>\n                            yyerror("newline in string");

<X_RULES,X_CODE1,X_CODE2>"/*"           yy_push_state(X_COMMENT);
<X_COMMENT>"/*"                         yy_push_state(X_COMMENT);
<X_COMMENT>"*/"                         yy_pop_state();
<X_COMMENT>.|\n                         ;

<X_RULES,X_CODE1,X_CODE2>"//".*$        ;
<X_CODE1>.                              ;
<X_CODE2>.|\n                           ;

<X_RULES>^"%%"                          ECHO; yy_pop_state();  /* code section */

<INITIAL,X_RULES>.|\n                   ECHO; /* echo the rest */

%%
int main() {
  return yylex();
}