(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: | ||
%% | %% | ||
− | </ | + | </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 yyparse(); | extern int yyparse(); | ||
int main() { return yyparse(); } | int main() { return yyparse(); } | ||
− | </ | + | </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'''): | ||
− | + | 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++ | + | g++ -std=c++17 -c lex.yy.c |
− | g++ -std=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]] |
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 (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 (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(); }
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