The Flex Lexical Analyzer/Exercise 4 - Removing the actions from a YACC specification

From Wiki**3

< The Flex Lexical Analyzer
Revision as of 21:53, 11 April 2010 by Root (talk | contribs) (The Solution)

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 ').

Exemplo: <text> %union { int i; } %token ID %type<i> expr %% expr : expr '+' expr { $$ = $1 + $3; }

    | ID            { $$ = $1; }
    ;

%% </text>

The Solution

[EXPLANATION COMING SOON]

<text> %option 8bit noyywrap yylineno stack %{

  1. 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_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;

} </text>