First-class citizens with only one member causing trouble.

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

First-class citizens with only one member causing trouble.

Florian Klemme

Hi,

I have a little compiler project in which Spirit Qi works just fine. But there is one little change I'd like to accomplish that causes quite some (compilation) trouble. Have a look at this code snippet.

// Instructions
instruction = (function_call        > ';')
            | (variable_declaration > ';')
            | (variable_assignment  > ';')
            | print_variable // Implicit semicolon TODO!!!?
            | print_text     // Implicit semicolon
            | scan_variable  // Implicit semicolon
            | if_else
            | while_loop
            | for_loop
            | instruction_block;

function_call        = function_name >> '(' > -(variable_name % ',') > ')';
variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u}));
variable_assignment  = variable_name >> '=' > expression;
print_variable       = qi::lexeme["print"] >> variable_name > ';';
print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
scan_variable        = qi::lexeme["scan"] > variable_name > ';';

Don't look to deep into what these rules are composed of, the only thing that matters is that the first three rules have their trailing ';' defined in the instruction rule and the others have their ';' in the rule itself.

I want to move all tailing ';' to the instruction rule as shown in the first few lines. For the first three rules this hasn't been a problem. The literal parser ';' doesn't affect the attribute of the rule so the position shouldn't matter.

But in fact, appending any literal parser before any "// Implicit semicolon" comment causes a compilation error. It took me some time to figure out why this is not a problem with the other rules. It turns out the problem is that the attribute of the problematic three rules are first-class citizens with only one member (which happens to be a string, not sure if this is relevant).

So the following ugly workaround actually leads to a compiling (and working) solution. By just adding a second member to the attribute of the rule.

diff --git a/bf/compiler.cpp b/bf/compiler.cpp
index 6f83c00..7cea53a 100644
--- a/bf/compiler.cpp
+++ b/bf/compiler.cpp
@@ -103,6 +103,7 @@ namespace instruction {
 
     struct print_variable_t {
         std::string variable_name;
+        int         dummy;
     };
 
     struct print_text_t {
@@ -253,7 +254,8 @@ BOOST_FUSION_ADAPT_STRUCT(
 
 BOOST_FUSION_ADAPT_STRUCT(
         bf::instruction::print_variable_t,
-        (std::string, variable_name))
+        (std::string, variable_name)
+        (int,         dummy))
 
 BOOST_FUSION_ADAPT_STRUCT(
         bf::instruction::print_text_t,
@@ -451,7 +453,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
         instruction = (function_call        > ';')
                     | (variable_declaration > ';')
                     | (variable_assignment  > ';')
-                    | print_variable // Implicit semicolon TODO!!!?
+                    | (print_variable       > ';') // TODO!!!?
                     | print_text     // Implicit semicolon
                     | scan_variable  // Implicit semicolon
                     | if_else
@@ -462,7 +464,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
         function_call        = function_name >> '(' > -(variable_name % ',') > ')';
         variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u}));
         variable_assignment  = variable_name >> '=' > expression;
-        print_variable       = qi::lexeme["print"] >> variable_name > ';';
+        print_variable       = qi::lexeme["print"] >> variable_name > qi::attr(0);
         print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
         scan_variable        = qi::lexeme["scan"] > variable_name > ';';
         if_else              = qi::lexeme["if"] > '(' > expression > ')' > instruction > -(qi::lexeme["else"] > instruction);

Have a look at https://github.com/Kruecke/BFGenerator if you want to check out the whole code. The critical section is this one: https://github.com/Kruecke/BFGenerator/blob/master/bf/compiler.cpp#L454. The workaround is committed in a branch as well: https://github.com/Kruecke/BFGenerator/compare/semicolon_workaround. If you want to run the code, make sure to run "make test" as the other rules don't compile this piece of code at the moment.

Please let me know if you have any idea how to fix this problem or what mistake I might have made. I am thankful for any ideas. Or is there a chance that this is a bug in Spirit Qi?

I tested this with different versions of Boost as well as different versions of gcc and msvc. C++14 support is required.

Florian


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: First-class citizens with only one member causing trouble.

Florian Klemme

I found another workaround I just don't understand. This works perfectly:

// Instructions
instruction = ( // Semicolon terminated instructions
                ( function_call
                | variable_declaration
                | variable_assignment
                | print_variable
                | print_text
                | scan_variable
                ) > ';')
            // Non-semicolon terminated instructions
            | if_else
            | while_loop
            | for_loop
            | instruction_block;

but this doesn't even compile:

// Instructions
instruction = (function_call        > ';')
            | (variable_declaration > ';')
            | (variable_assignment  > ';')
            | (print_variable       > ';')
            | (print_text           > ';')
            | (scan_variable        > ';')
            | if_else
            | while_loop
            | for_loop
            | instruction_block;


On 29.07.2016 18:30, Florian Klemme wrote:

Hi,

I have a little compiler project in which Spirit Qi works just fine. But there is one little change I'd like to accomplish that causes quite some (compilation) trouble. Have a look at this code snippet.

// Instructions
instruction = (function_call        > ';')
            | (variable_declaration > ';')
            | (variable_assignment  > ';')
            | print_variable // Implicit semicolon TODO!!!?
            | print_text     // Implicit semicolon
            | scan_variable  // Implicit semicolon
            | if_else
            | while_loop
            | for_loop
            | instruction_block;

function_call        = function_name >> '(' > -(variable_name % ',') > ')';
variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u}));
variable_assignment  = variable_name >> '=' > expression;
print_variable       = qi::lexeme["print"] >> variable_name > ';';
print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
scan_variable        = qi::lexeme["scan"] > variable_name > ';';

Don't look to deep into what these rules are composed of, the only thing that matters is that the first three rules have their trailing ';' defined in the instruction rule and the others have their ';' in the rule itself.

I want to move all tailing ';' to the instruction rule as shown in the first few lines. For the first three rules this hasn't been a problem. The literal parser ';' doesn't affect the attribute of the rule so the position shouldn't matter.

But in fact, appending any literal parser before any "// Implicit semicolon" comment causes a compilation error. It took me some time to figure out why this is not a problem with the other rules. It turns out the problem is that the attribute of the problematic three rules are first-class citizens with only one member (which happens to be a string, not sure if this is relevant).

So the following ugly workaround actually leads to a compiling (and working) solution. By just adding a second member to the attribute of the rule.

diff --git a/bf/compiler.cpp b/bf/compiler.cpp
index 6f83c00..7cea53a 100644
--- a/bf/compiler.cpp
+++ b/bf/compiler.cpp
@@ -103,6 +103,7 @@ namespace instruction {
 
     struct print_variable_t {
         std::string variable_name;
+        int         dummy;
     };
 
     struct print_text_t {
@@ -253,7 +254,8 @@ BOOST_FUSION_ADAPT_STRUCT(
 
 BOOST_FUSION_ADAPT_STRUCT(
         bf::instruction::print_variable_t,
-        (std::string, variable_name))
+        (std::string, variable_name)
+        (int,         dummy))
 
 BOOST_FUSION_ADAPT_STRUCT(
         bf::instruction::print_text_t,
@@ -451,7 +453,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
         instruction = (function_call        > ';')
                     | (variable_declaration > ';')
                     | (variable_assignment  > ';')
-                    | print_variable // Implicit semicolon TODO!!!?
+                    | (print_variable       > ';') // TODO!!!?
                     | print_text     // Implicit semicolon
                     | scan_variable  // Implicit semicolon
                     | if_else
@@ -462,7 +464,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
         function_call        = function_name >> '(' > -(variable_name % ',') > ')';
         variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u}));
         variable_assignment  = variable_name >> '=' > expression;
-        print_variable       = qi::lexeme["print"] >> variable_name > ';';
+        print_variable       = qi::lexeme["print"] >> variable_name > qi::attr(0);
         print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
         scan_variable        = qi::lexeme["scan"] > variable_name > ';';
         if_else              = qi::lexeme["if"] > '(' > expression > ')' > instruction > -(qi::lexeme["else"] > instruction);

Have a look at https://github.com/Kruecke/BFGenerator if you want to check out the whole code. The critical section is this one: https://github.com/Kruecke/BFGenerator/blob/master/bf/compiler.cpp#L454. The workaround is committed in a branch as well: https://github.com/Kruecke/BFGenerator/compare/semicolon_workaround. If you want to run the code, make sure to run "make test" as the other rules don't compile this piece of code at the moment.

Please let me know if you have any idea how to fix this problem or what mistake I might have made. I am thankful for any ideas. Or is there a chance that this is a bug in Spirit Qi?

I tested this with different versions of Boost as well as different versions of gcc and msvc. C++14 support is required.

Florian



------------------------------------------------------------------------------


_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: First-class citizens with only one member causing trouble.

Frank Hein
Hi Florian, 


Regarding your compiler implementation did you examine the mini-c example provided with qi? Inspiring. 

Regards, Frank


Von meinem iPhone gesendet

Am 31.07.2016 um 19:10 schrieb Florian Klemme <[hidden email]>:

I found another workaround I just don't understand. This works perfectly:

// Instructions
instruction = ( // Semicolon terminated instructions
                ( function_call
                | variable_declaration
                | variable_assignment
                | print_variable
                | print_text
                | scan_variable
                ) > ';')
            // Non-semicolon terminated instructions
            | if_else
            | while_loop
            | for_loop
            | instruction_block;

but this doesn't even compile:

// Instructions
instruction = (function_call        > ';')
            | (variable_declaration > ';')
            | (variable_assignment  > ';')
            | (print_variable       > ';')
            | (print_text           > ';')
            | (scan_variable        > ';')
            | if_else
            | while_loop
            | for_loop
            | instruction_block;


On 29.07.2016 18:30, Florian Klemme wrote:

Hi,

I have a little compiler project in which Spirit Qi works just fine. But there is one little change I'd like to accomplish that causes quite some (compilation) trouble. Have a look at this code snippet.

// Instructions
instruction = (function_call        > ';')
            | (variable_declaration > ';')
            | (variable_assignment  > ';')
            | print_variable // Implicit semicolon TODO!!!?
            | print_text     // Implicit semicolon
            | scan_variable  // Implicit semicolon
            | if_else
            | while_loop
            | for_loop
            | instruction_block;

function_call        = function_name >> '(' > -(variable_name % ',') > ')';
variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u}));
variable_assignment  = variable_name >> '=' > expression;
print_variable       = qi::lexeme["print"] >> variable_name > ';';
print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
scan_variable        = qi::lexeme["scan"] > variable_name > ';';

Don't look to deep into what these rules are composed of, the only thing that matters is that the first three rules have their trailing ';' defined in the instruction rule and the others have their ';' in the rule itself.

I want to move all tailing ';' to the instruction rule as shown in the first few lines. For the first three rules this hasn't been a problem. The literal parser ';' doesn't affect the attribute of the rule so the position shouldn't matter.

But in fact, appending any literal parser before any "// Implicit semicolon" comment causes a compilation error. It took me some time to figure out why this is not a problem with the other rules. It turns out the problem is that the attribute of the problematic three rules are first-class citizens with only one member (which happens to be a string, not sure if this is relevant).

So the following ugly workaround actually leads to a compiling (and working) solution. By just adding a second member to the attribute of the rule.

diff --git a/bf/compiler.cpp b/bf/compiler.cpp
index 6f83c00..7cea53a 100644
--- a/bf/compiler.cpp
+++ b/bf/compiler.cpp
@@ -103,6 +103,7 @@ namespace instruction {
 
     struct print_variable_t {
         std::string variable_name;
+        int         dummy;
     };
 
     struct print_text_t {
@@ -253,7 +254,8 @@ BOOST_FUSION_ADAPT_STRUCT(
 
 BOOST_FUSION_ADAPT_STRUCT(
         bf::instruction::print_variable_t,
-        (std::string, variable_name))
+        (std::string, variable_name)
+        (int,         dummy))
 
 BOOST_FUSION_ADAPT_STRUCT(
         bf::instruction::print_text_t,
@@ -451,7 +453,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
         instruction = (function_call        > ';')
                     | (variable_declaration > ';')
                     | (variable_assignment  > ';')
-                    | print_variable // Implicit semicolon TODO!!!?
+                    | (print_variable       > ';') // TODO!!!?
                     | print_text     // Implicit semicolon
                     | scan_variable  // Implicit semicolon
                     | if_else
@@ -462,7 +464,7 @@ struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
         function_call        = function_name >> '(' > -(variable_name % ',') > ')';
         variable_declaration = qi::lexeme["var"] > variable_name > (('=' > expression) | qi::attr(expression::value_t{0u}));
         variable_assignment  = variable_name >> '=' > expression;
-        print_variable       = qi::lexeme["print"] >> variable_name > ';';
+        print_variable       = qi::lexeme["print"] >> variable_name > qi::attr(0);
         print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
         scan_variable        = qi::lexeme["scan"] > variable_name > ';';
         if_else              = qi::lexeme["if"] > '(' > expression > ')' > instruction > -(qi::lexeme["else"] > instruction);

Have a look at https://github.com/Kruecke/BFGenerator if you want to check out the whole code. The critical section is this one: https://github.com/Kruecke/BFGenerator/blob/master/bf/compiler.cpp#L454. The workaround is committed in a branch as well: https://github.com/Kruecke/BFGenerator/compare/semicolon_workaround. If you want to run the code, make sure to run "make test" as the other rules don't compile this piece of code at the moment.

Please let me know if you have any idea how to fix this problem or what mistake I might have made. I am thankful for any ideas. Or is there a chance that this is a bug in Spirit Qi?

I tested this with different versions of Boost as well as different versions of gcc and msvc. C++14 support is required.

Florian



------------------------------------------------------------------------------


_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: First-class citizens with only one member causing trouble.

sehe
On 03-08-16 01:59, Frank Hein wrote:


------------------------------------------------------------------------------


_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

I still can't see any (literally) of your emails. It's certainly my MUA, but since it only manifests with your posts, maybe you can check whether something can be simplified on your end?


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Mini-C example

Florian Klemme
In reply to this post by Frank Hein
On 03.08.2016 01:59, Frank Hein wrote:
Regarding your compiler implementation did you examine the mini-c example provided with qi? Inspiring.
Oh, it is! I haven't seen it before. I see, there is a lot of refactorization for me to do. ;-)

I've seen that Joel uses multiple grammars to parse the source, but I can only find the instantiation of the function-parser in main(). Where are the others instantiated? Or how does this chain of grammars work?

Also, what does this "body" member do?

    template <typename Iterator>
    function<Iterator>::function(error_handler<Iterator>& error_handler)
      : function::base_type(start), body(error_handler)
name =
                !body.expr.keywords
            >>  raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
            ;

Florian


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Mini-C example

Frank Hein
Florian Klemme <[hidden email]> wrote on 03.08.2016 17:34:21:

> From: Florian Klemme <[hidden email]>
> To: [hidden email],
> Date: 03.08.2016 17:36
> Subject: [Spirit-general] Mini-C example
>
> On 03.08.2016 01:59, Frank Hein wrote:
> Regarding your compiler implementation did you examine the mini-c
> example provided with qi? Inspiring.
> Oh, it is! I haven't seen it before. I see, there is a lot of
> refactorization for me to do. ;-)

> I've seen that Joel uses multiple grammars to parse the source, but
> I can only find the instantiation of the function-parser in main().

You can understand grammars as a container for rules. You can use them
to give some structure (by topic, for example) to your rule set.

A grammar is also a nonterminal parser. When you define a grammer, you
provide a start rule, which is one of the rules defined within the
grammar.

That's not all about grammars but enough to get a basic understanding.

If you phrase_parse an input with a grammar provided as parser, then qi
applies
the rules defined in the grammer starting with the defined start rule.
This
may depend on other rules.


> Where are the others instantiated? Or how does this chain of grammars
work?
> Also, what does this "body" member do?
>     template <typename Iterator>
>     function<Iterator>::function(error_handler<Iterator>& error_handler)
>       : function::base_type(start), body(error_handler)

Above function::base_type(start) makes the rule named 'start' the start
rule
of the grammar 'function'.

So if you would phrase_parse( x,y, function, skipper) rule evalution
starts
at the 'start' rule.

> name =
>                 !body.expr.keywords
>             >>  raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
>             ;

You can even make a grammar known from another grammar. Take a look at
the declaration of body. It's statement<Iterator> body. This is the
statement
grammar declared in statement.hpp. The statement grammar again has a
member, which is
the expression grammar.

That way the mini-c grammars have a top-down knowledge of each other. In
main only the
top level grammar is explicitly, the others are instantiated as a (chain
of) members of
the outer grammar.

Regards, Frank


> Florian
>
------------------------------------------------------------------------------
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Mini-C example

Florian Klemme

Oh, right. I haven't seen the declaration of "body" in function.hpp and thought it would be a member inherited from qi::grammar.

This makes sense, thanks a lot! :-)

Florian


On 03.08.2016 18:27, Frank Hein wrote:
Florian Klemme [hidden email] wrote on 03.08.2016 17:34:21:

From: Florian Klemme [hidden email]
To: [hidden email], 
Date: 03.08.2016 17:36
Subject: [Spirit-general] Mini-C example

On 03.08.2016 01:59, Frank Hein wrote:
Regarding your compiler implementation did you examine the mini-c 
example provided with qi? Inspiring. 
Oh, it is! I haven't seen it before. I see, there is a lot of 
refactorization for me to do. ;-) 

I've seen that Joel uses multiple grammars to parse the source, but 
I can only find the instantiation of the function-parser in main(). 
You can understand grammars as a container for rules. You can use them
to give some structure (by topic, for example) to your rule set. 

A grammar is also a nonterminal parser. When you define a grammer, you
provide a start rule, which is one of the rules defined within the 
grammar.

That's not all about grammars but enough to get a basic understanding.

If you phrase_parse an input with a grammar provided as parser, then qi 
applies
the rules defined in the grammer starting with the defined start rule. 
This
may depend on other rules. 


Where are the others instantiated? Or how does this chain of grammars 
work?
Also, what does this "body" member do?
    template <typename Iterator>
    function<Iterator>::function(error_handler<Iterator>& error_handler)
      : function::base_type(start), body(error_handler)
Above function::base_type(start) makes the rule named 'start' the start 
rule
of the grammar 'function'.

So if you would phrase_parse( x,y, function, skipper) rule evalution 
starts
at the 'start' rule.

name =
                !body.expr.keywords
            >>  raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
            ;
You can even make a grammar known from another grammar. Take a look at
the declaration of body. It's statement<Iterator> body. This is the 
statement
grammar declared in statement.hpp. The statement grammar again has a 
member, which is
the expression grammar. 

That way the mini-c grammars have a top-down knowledge of each other. In 
main only the 
top level grammar is explicitly, the others are instantiated as a (chain 
of) members of
the outer grammar.

Regards, Frank


Florian

------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general


------------------------------------------------------------------------------


_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Mini-C example

Frank Hein
Florian Klemme <[hidden email]> wrote on 03.08.2016 18:37:06:

> From: Florian Klemme <[hidden email]>
> To: [hidden email],
> Date: 03.08.2016 18:38
> Subject: Re: [Spirit-general] Mini-C example
>
> Oh, right. I haven't seen the declaration of "body" in function.hpp
> and thought it would be a member inherited from qi::grammar.
> This makes sense, thanks a lot! :-)
> Florian

You're welcome. Happy refactoring. :)

>
> On 03.08.2016 18:27, Frank Hein wrote:
> Florian Klemme <[hidden email]> wrote on 03.08.2016 17:34:21:
>

> From: Florian Klemme <[hidden email]>
> To: [hidden email],
> Date: 03.08.2016 17:36
> Subject: [Spirit-general] Mini-C example
>
> On 03.08.2016 01:59, Frank Hein wrote:
> Regarding your compiler implementation did you examine the mini-c
> example provided with qi? Inspiring.
> Oh, it is! I haven't seen it before. I see, there is a lot of
> refactorization for me to do. ;-)

>
>

> I've seen that Joel uses multiple grammars to parse the source, but
> I can only find the instantiation of the function-parser in main().

>
> You can understand grammars as a container for rules. You can use them
> to give some structure (by topic, for example) to your rule set.
>
> A grammar is also a nonterminal parser. When you define a grammer, you
> provide a start rule, which is one of the rules defined within the
> grammar.
>
> That's not all about grammars but enough to get a basic understanding.
>
> If you phrase_parse an input with a grammar provided as parser, then qi
> applies
> the rules defined in the grammer starting with the defined start rule.
> This
> may depend on other rules.
>
>

> Where are the others instantiated? Or how does this chain of grammars

> work?

> Also, what does this "body" member do?
>     template <typename Iterator>
>     function<Iterator>::function(error_handler<Iterator>& error_handler)
>       : function::base_type(start), body(error_handler)

>
> Above function::base_type(start) makes the rule named 'start' the start
> rule
> of the grammar 'function'.
>
> So if you would phrase_parse( x,y, function, skipper) rule evalution
> starts
> at the 'start' rule.
>

> name =
>                 !body.expr.keywords
>             >>  raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
>             ;

>
> You can even make a grammar known from another grammar. Take a look at
> the declaration of body. It's statement<Iterator> body. This is the
> statement
> grammar declared in statement.hpp. The statement grammar again has a
> member, which is
> the expression grammar.
>
> That way the mini-c grammars have a top-down knowledge of each other. In

> main only the
> top level grammar is explicitly, the others are instantiated as a (chain

> of) members of
> the outer grammar.
>
> Regards, Frank
>
>

> Florian
>

>
------------------------------------------------------------------------------

> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
>

>
------------------------------------------------------------------------------

>

> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general

>
------------------------------------------------------------------------------
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

smime.p7s (6K) Download Attachment