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

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...")
 
Line 9: Line 9:
  
 
The lexical analyzer ('''minint.l''') is very simple and limited to recognizing the indispensable tokens.
 
The lexical analyzer ('''minint.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 ('''minint.y''') will be built to immediately compute the maximum values in a syntax-directed fashion (as they occur). Note that the use of numeric limits is correct, but other such names would be acceptable (e.g. '''MAXDOUBLE''').
 
The syntactic analyzer ('''minint.y''') will be built to immediately compute the maximum values in a syntax-directed fashion (as they occur). Note that the use of numeric limits is correct, but other such names would be acceptable (e.g. '''MAXDOUBLE''').
<text>
+
<source lang="text">
 
%{
 
%{
 
#include <limits>
 
#include <limits>
Line 60: Line 60:
 
extern int yyparse();
 
extern int yyparse();
 
int main() { return yyparse(); }
 
int main() { return yyparse(); }
</text>
+
</source>
  
 
== How to Compile? ==
 
== How to Compile? ==

Revision as of 13:22, 12 February 2019

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 menor 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 (minint.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 (minint.y) will be built to immediately compute the maximum values in a syntax-directed fashion (as they occur). Note that the use of numeric limits is correct, but other such names would be acceptable (e.g. MAXDOUBLE).

%{
#include <limits>
#include <iostream>
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 << "shortest interval: " << $1 << std::endl; }
    | /* empty */ { std::cout << "empty sequence"            << std::endl; }
    ;

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

interval : tDOUBLE ':' tDOUBLE { $$ = $1 > $3 ? std::numeric_limits<double>::max() : $3 - $1; }
         ;

%%
extern int yylex();
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 minint.l

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

 byacc -dtv minint.y

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++11 -c y.tab.c
 g++ -o minint y.tab.o lex.yy.o