Difference between revisions of "The Flex Lexical Analyzer/Exercise 4 - Removing the actions from a YACC 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 YACC e que a copie para a saída sem as acções semâ...)
 
 
(18 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação YACC e que a copie para a saída sem as acções semânticas associadas às regras. Codifique todas as rotinas auxiliares.
 
Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação YACC e que a copie para a saída sem as acções semânticas associadas às regras. Codifique todas as rotinas auxiliares.
  
A especificação YACC, tal como a do 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.
+
A especificação YACC, tal como a do 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.
  
Cada regra YACC começa com um símbolo não terminal, seguido por : e por uma sequência de símbolos terminais e não terminais, acções semânticas e, eventualmente, alternativas (indicadas por|). Cada regra é terminada por ;. As acções semânticas são delimitadas por {} e podem conter código C/C++ arbitrário. Os identificadores dos símbolos começam com uma letra que pode ser seguida por caracteres  alfanuméricos ou _. Caracteres individuais podem aparecer como terminais (delimitados por ').
+
Cada regra YACC começa com um símbolo não terminal, seguido por : e por uma sequência de símbolos terminais e não terminais, acções semânticas e, eventualmente, alternativas (indicadas por <strong>|</strong>). Cada regra é terminada por <strong>;</strong>. As acções semânticas são delimitadas por {} e podem conter código C/C++ arbitrário. Os identificadores dos símbolos começam com uma letra que pode ser seguida por caracteres  alfanuméricos ou <strong>_</strong> Caracteres individuais podem aparecer como terminais (delimitados por plicas <strong>'</strong>).
  
Exemplo:
+
{{CollapsedCode|Exemplo de entrada e de saída|
<text>
+
<table>
 +
<tr><th>Entrada</th><th>Saída</th></tr>
 +
<tr><td><source lang="text">
 
%union { int i; }
 
%union { int i; }
 
%token<i> ID
 
%token<i> ID
Line 17: Line 19:
 
     ;
 
     ;
 
%%
 
%%
</text>
+
</source></td>
 +
<td><source lang="text">
 +
%union { int i; }
 +
%token<i> ID
 +
%type<i> expr
 +
%%
 +
expr : expr '+' expr
 +
    | ID
 +
    ;
 +
%%
 +
</source>
 +
</td></tr></table>
 +
}}
  
 
== The Solution ==
 
== The Solution ==
  
<text>
+
This solution assumes that comments only occur in actions in the rules section.
 +
 
 +
[EXPLANATION COMING SOON]
 +
{{CollapsedCode|Solução|
 +
<source lang="text">
 
%option 8bit noyywrap yylineno stack
 
%option 8bit noyywrap yylineno stack
 
%{
 
%{
Line 42: Line 60:
  
 
<X_RULES>"{"    yy_push_state(X_CODE);
 
<X_RULES>"{"    yy_push_state(X_CODE);
 +
<X_CODE>"{"    yy_push_state(X_CODE);
 
<X_CODE>"}"    yy_pop_state();
 
<X_CODE>"}"    yy_pop_state();
  
Line 74: Line 93:
 
   return 0;
 
   return 0;
 
}
 
}
</text>
+
</source>
 +
}}
  
[[category:Compilers]]
+
[[category:Compiladores|Flex Lexical Analyzer]]
[[category:Teaching]]
+
[[category:Ensino]]

Latest revision as of 13:44, 4 March 2019

The Problem (in Portuguese)

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

A especificação YACC, tal como a do 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.

Cada regra YACC começa com um símbolo não terminal, seguido por : e por uma sequência de símbolos terminais e não terminais, acções semânticas e, eventualmente, alternativas (indicadas por |). Cada regra é terminada por ;. As acções semânticas são delimitadas por {} e podem conter código C/C++ arbitrário. Os identificadores dos símbolos começam com uma letra que pode ser seguida por caracteres alfanuméricos ou _ Caracteres individuais podem aparecer como terminais (delimitados por plicas ').

Exemplo de entrada e de saída
EntradaSaída
%union { int i; }
%token<i> ID
%type<i> expr
%%
expr : expr '+' expr { $$ = $1 + $3; }
     | ID            { $$ = $1; }
     ;
%%
%union { int i; }
%token<i> ID
%type<i> expr 
%%
expr : expr '+' expr
     | ID
     ;
%%

The Solution

This solution assumes that comments only occur in actions in the rules section.

[EXPLANATION COMING SOON]

Solução
%option 8bit noyywrap yylineno stack
%{
#include <iostream>
int count = 0;
inline void yyerror(const char *msg) {
  std::cerr << "Error at " << yylineno << ": " << msg << std::endl;
}
%}
%x X_STRIGN X_COMMENT X_CHAR X_CHARIGN X_CODE X_RULES
%%

^"%%"           yy_push_state(X_RULES);

<X_RULES>\'     yy_push_state(X_CHAR); ECHO;
<X_CHAR>\'      yy_pop_state(); ECHO;
<X_CHAR>\\\'    ECHO;
<X_CHAR>.       ECHO;
<X_CHAR>\n      yyerror("newline in char");

<X_RULES>"{"    yy_push_state(X_CODE);
<X_CODE>"{"     yy_push_state(X_CODE);
<X_CODE>"}"     yy_pop_state();

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

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

<X_CODE>"/*"    yy_push_state(X_COMMENT);
<X_COMMENT>"/*" yy_push_state(X_COMMENT);
<X_COMMENT>"*/" yy_pop_state();
<X_COMMENT>.|\n ;

<X_CODE>"//".*$ ;
<X_CODE>.|\n    ;

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

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

%%
int main() {
  yylex();
  std::cout << count << std::endl;
  return 0;
}