tutorial 2 -- hello world γ

This time is parameter of semantic action.

The Grammar File

%token Hello<std::string> World<std::string>;
%namespace hello_world;
%dont_use_stl;

HelloWorld<std::string> : [Greet] Hello(0) World(1);

The difference from hello1 are two points:

At Line 1, capar will be recognize the types of Hello => std::string, World => std::string by type specification for token. By this, if token was given at later grammar, then the parser regards the type of the semantic value is the same type as associated one.

At Line 5, it specifies the parameter on Greet call. The part of "(digit)" is just it. This digit indicates n of n-th parameter (base is zero). The symbols without "(digit)" won't be used on the call of its semantic action. By this definition, the 0-th parameter of Greet is the value of Hello, the 1-th parameter is the value of World, correspondingly.

The Calling File

#include <string>
#include <iostream>
#include "hello2.hpp"

struct SemanticAction {
    void syntax_error(){}
    void stack_overflow(){}
    void upcast( std::string& x, const std::string& y ) { x = y; }
    void downcast( std::string& x, const std::string& y ) { x = y; }

    std::string Greet( const std::string& x, const std::string& y )
    {
        std::cout << x << y << std::endl; return "";
    }
};

int main( int, char** )
{
    SemanticAction sa;
    hello_world::Parser< std::string, SemanticAction > parser( sa );

    parser.post( hello_world::token_Hello, "Guten Tag, " );
    parser.post( hello_world::token_World, "Welt" );
    parser.post( hello_world::token_eof, "" );

    return 0;
}

The semantic actions became a bit compilicated.

This time introduced "downcast" is a function to provide conversion from type Value of Parser, to each type of symbol. It's just a inverse of upcast. This time, "the type of the whole set of semantic values" is std::string, the "individual type" is also std::string (Either of Hello, World, HelloWorld is std::string type). Thus it's just one line of "void downcast( std::string& x, const std::string& y ) { x = y; }".

The signature of Greet is given as below:

std::string Greet( const std::string& x, const std::string& y );
		

As the grammar file specified, x indicates the value associated to Hello, y indicates the value associated to World, correspondingly. And then, the return value of this function is associated to HelloWorld by the parser.

This time, the main function passes a value of "Guten Tag, ", "Welt" when token is post'ed. That is, this value is used as the associated value to Hello and World on HelloWorld acceptance.

Execution

% ./hello2
Guten Tag, Welt