|
|
Line 1: |
Line 1: |
| {{TOCright}}
| | #REDIRECT [[ist:The YACC Parser Generator/Exercise 7]] |
| == 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.
| |
| <text>
| |
| %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 */
| |
| | |
| %%
| |
| </text>
| |
| | |
| == 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''').
| |
| <text>
| |
| %{
| |
| #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(); }
| |
| </text>
| |
| | |
| == 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
| |
| | |
| [[category:Compiladores]]
| |
| [[category:Ensino]]
| |