Difference between revisions of "The YACC Parser Generator/Exercise 6"

From Wiki**3

< The YACC Parser Generator
(Created page with "{{TOCright}} == Problema == Considere uma linguagem constituída por uma sequência de intervalos, possivelmente vazia. Os intervalos são definidos por valores reais (os li...")
 
(How to Compile?)
 
(4 intermediate revisions by the same user not shown)
Line 9: Line 9:
  
 
The lexical analyzer ('''maxint.l''') is very simple and limited to recognizing the indispensable tokens.
 
The lexical analyzer ('''maxint.l''') is very simple and limited to recognizing the indispensable tokens.
<text>
+
<source lang="text">
 
%option noyywrap
 
%option noyywrap
 
%{
 
%{
Line 26: Line 26:
  
 
%%
 
%%
</text>
+
</source>
  
 
== The Syntactic Analyzer (YACC) Specification ==
 
== The Syntactic Analyzer (YACC) Specification ==
  
 
The syntactic analyzer ('''maxint.y''') will be built to immediately compute the maximum values in a syntax-directed fashion (as they occur).
 
The syntactic analyzer ('''maxint.y''') will be built to immediately compute the maximum values in a syntax-directed fashion (as they occur).
<text>
+
<source lang="text">
 
%{
 
%{
 
#include <limits>
 
#include <limits>
 
#include <iostream>
 
#include <iostream>
 +
extern int yylex();
 
inline void yyerror(const char *msg) { std::cerr << msg << std::endl; }
 
inline void yyerror(const char *msg) { std::cerr << msg << std::endl; }
 
%}
 
%}
Line 57: Line 58:
  
 
%%
 
%%
extern int yylex();
 
 
extern int yyparse();
 
extern int yyparse();
 
int main() { return yyparse(); }
 
int main() { return yyparse(); }
</text>
+
</source>
  
 
== How to Compile? ==
 
== How to Compile? ==
Line 70: Line 70:
 
The YACC specification is processed as follows (files '''y.tab.h''', needed by the Flex-generated code, and '''y.tab.c'''):
 
The YACC specification is processed as follows (files '''y.tab.h''', needed by the Flex-generated code, and '''y.tab.c'''):
  
   byacc -dtv maxint.y
+
   bison -dtv maxint.y
  
 
Compiling the C/C++ code (it is C++ simply because we programmed the extra code in that language):
 
Compiling the C/C++ code (it is C++ simply because we programmed the extra code in that language):
  
   g++ -std=c++11 -c lex.yy.c
+
   g++ -std=c++17 -c lex.yy.c
   g++ -std=c++11 -c y.tab.c
+
   g++ -std=c++17 -c y.tab.c
 
   g++ -o maxint y.tab.o lex.yy.o
 
   g++ -o maxint y.tab.o lex.yy.o
  
 
[[category:Compiladores]]
 
[[category:Compiladores]]
 
[[category:Ensino]]
 
[[category:Ensino]]

Latest revision as of 15:33, 21 April 2021

Problema

Considere uma linguagem constituída por uma sequência de intervalos, possivelmente vazia. Os intervalos são definidos por valores reais (os limites inferior e superior são separados por :). Os intervalos são separados entre si por vírgulas (,). A representação dos números reais é como em C++. Pretende-se determinar a largura do maior intervalo da sequência, ignorando os intervalos inválidos (em que o limite superior é menor que o limite inferior).

Escreva uma especificação YACC para o problema acima. Codifique toda a especificação (incluindo as zonas de declarações e de regras) e todas as funções auxiliares. Não utilizar variáveis globais.

The Lexical Analyzer (Flex) Specification

The lexical analyzer (maxint.l) is very simple and limited to recognizing the indispensable tokens.

%option noyywrap
%{
#include <string>
#include "y.tab.h"
%}
%%

[0-9]*\.[0-9]+([Ee][-+]?[0-9]+)?        yylval.d = std::stod(yytext); return tDOUBLE;
[0-9]+\.[0-9]*([Ee][-+]?[0-9]+)?        yylval.d = std::stod(yytext); return tDOUBLE;
[0-9]+([Ee][-+]?[0-9]+)                 yylval.d = std::stod(yytext); return tDOUBLE;

[,:]                                    return *yytext;

.|\n                                    ; /* ignore the rest */

%%

The Syntactic Analyzer (YACC) Specification

The syntactic analyzer (maxint.y) will be built to immediately compute the maximum values in a syntax-directed fashion (as they occur).

%{
#include <limits>
#include <iostream>
extern int yylex();
inline void yyerror(const char *msg) { std::cerr << msg << std::endl; }
%}

%union { double d; }

%token <d> tDOUBLE
%type  <d> sequence interval

%%

top : sequence    { std::cout << "longest interval: " << $1 << std::endl; }
    | /* empty */ { std::cout << "empty sequence"           << std::endl; }
    ;

sequence : interval              { $$ = $1; }
         | sequence ',' interval { $$ = std::max($1, $3); }
         ;

interval : tDOUBLE ':' tDOUBLE { $$ = $1 > $3 ? -1 : $3 - $1; }
         ;

%%
extern int yyparse();
int main() { return yyparse(); }

How to Compile?

The Flex specification is processed as follows (the file lex.yy.c is produced):

 flex maxint.l

The YACC specification is processed as follows (files y.tab.h, needed by the Flex-generated code, and y.tab.c):

 bison -dtv maxint.y

Compiling the C/C++ code (it is C++ simply because we programmed the extra code in that language):

 g++ -std=c++17 -c lex.yy.c
 g++ -std=c++17 -c y.tab.c
 g++ -o maxint y.tab.o lex.yy.o