Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75896 - branches/quickbook-dev/tools/quickbook/src
From: dnljms_at_[hidden]
Date: 2011-12-11 06:15:10


Author: danieljames
Date: 2011-12-11 06:15:09 EST (Sun, 11 Dec 2011)
New Revision: 75896
URL: http://svn.boost.org/trac/boost/changeset/75896

Log:
Quickbook: Stateful actions class for syntax highlighter.
Text files modified:
   branches/quickbook-dev/tools/quickbook/src/syntax_highlight.cpp | 316 +++++++++++++++++++++------------------
   1 files changed, 170 insertions(+), 146 deletions(-)

Modified: branches/quickbook-dev/tools/quickbook/src/syntax_highlight.cpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/syntax_highlight.cpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/syntax_highlight.cpp 2011-12-11 06:15:09 EST (Sun, 11 Dec 2011)
@@ -26,98 +26,90 @@
     // It's named differently to distinguish it from the syntax highlighting
     // actions, declared below.
 
- // Syntax Highlight Actions
-
- struct span
+ template <typename T, typename Value>
+ struct member_action_value
     {
- // Decorates c++ code fragments
+ typedef void(T::*member_function)(Value);
 
- span(char const* name, collector& out)
- : name(name), out(out) {}
+ T& l;
+ member_function mf;
 
- void operator()(parse_iterator first, parse_iterator last) const;
+ member_action_value(T& l, member_function mf) : l(l), mf(mf) {}
 
- char const* name;
- collector& out;
+ void operator()(Value v) const {
+ (l.*mf)(v);
+ }
     };
 
- struct span_start
+ template <typename T>
+ struct member_action
     {
- span_start(char const* name, collector& out)
- : name(name), out(out) {}
+ typedef void(T::*member_function)(parse_iterator, parse_iterator);
 
- void operator()(parse_iterator first, parse_iterator last) const;
+ T& l;
+ member_function mf;
 
- char const* name;
- collector& out;
- };
+ member_action(T& l, member_function mf) : l(l), mf(mf) {}
 
- struct span_end
- {
- span_end(collector& out)
- : out(out) {}
-
- void operator()(parse_iterator first, parse_iterator last) const;
-
- collector& out;
+ void operator()(parse_iterator first, parse_iterator last) const {
+ (l.*mf)(first, last);
+ }
     };
 
- struct unexpected_char
+ template <typename T, typename Arg1>
+ struct member_action1
     {
- // Handles unexpected chars in c++ syntax
+ typedef void(T::*member_function)(parse_iterator, parse_iterator, Arg1);
 
- unexpected_char(
- collector& out
- , quickbook::actions& escape_actions)
- : out(out)
- , escape_actions(escape_actions) {}
+ T& l;
+ member_function mf;
 
- void operator()(parse_iterator first, parse_iterator last) const;
+ member_action1(T& l, member_function mf) : l(l), mf(mf) {}
 
- collector& out;
- quickbook::actions& escape_actions;
- };
-
- struct plain_char
- {
- // Prints a single plain char.
- // Converts '<' to "&lt;"... etc See utils.hpp
+ struct impl
+ {
+ member_action1 a;
+ Arg1 value;
 
- plain_char(collector& out)
- : out(out) {}
+ impl(member_action1& a, Arg1 value) :
+ a(a), value(value)
+ {}
 
- void operator()(char ch) const;
- void operator()(parse_iterator first, parse_iterator last) const;
+ void operator()(parse_iterator first, parse_iterator last) const {
+ (a.l.*a.mf)(first, last, value);
+ }
+ };
 
- collector& out;
+ impl operator()(Arg1 a1) {
+ return impl(*this, a1);
+ }
     };
 
- struct pre_escape_back
- {
- // Escapes back from code to quickbook (Pre)
-
- pre_escape_back(actions& escape_actions)
- : escape_actions(escape_actions) {}
-
- void operator()(parse_iterator first, parse_iterator last) const;
-
- actions& escape_actions;
- };
+ // Syntax Highlight Actions
 
- struct post_escape_back
+ struct syntax_highlight_actions
     {
- // Escapes back from code to quickbook (Post)
-
- post_escape_back(collector& out, actions& escape_actions)
- : out(out), escape_actions(escape_actions) {}
-
- void operator()(parse_iterator first, parse_iterator last) const;
+ quickbook::collector out;
+ quickbook::actions& escape_actions;
+ do_macro_action do_macro_impl;
 
- collector& out;
- actions& escape_actions;
+ syntax_highlight_actions(quickbook::actions& escape_actions) :
+ out(), escape_actions(escape_actions),
+ do_macro_impl(out, escape_actions)
+ {}
+
+ void span(parse_iterator, parse_iterator, char const*);
+ void span_start(parse_iterator, parse_iterator, char const*);
+ void span_end(parse_iterator, parse_iterator);
+ void unexpected_char(parse_iterator, parse_iterator);
+ void plain_char(parse_iterator, parse_iterator);
+ void pre_escape_back(parse_iterator, parse_iterator);
+ void post_escape_back(parse_iterator, parse_iterator);
+ void do_macro(std::string const&);
     };
 
- void span::operator()(parse_iterator first, parse_iterator last) const
+ void syntax_highlight_actions::span(parse_iterator first,
+ parse_iterator last, char const* name)
     {
         out << "<phrase role=\"" << name << "\">";
         while (first != last)
@@ -125,21 +117,24 @@
         out << "</phrase>";
     }
 
- void span_start::operator()(parse_iterator first, parse_iterator last) const
+ void syntax_highlight_actions::span_start(parse_iterator first,
+ parse_iterator last, char const* name)
     {
         out << "<phrase role=\"" << name << "\">";
         while (first != last)
             detail::print_char(*first++, out.get());
     }
 
- void span_end::operator()(parse_iterator first, parse_iterator last) const
+ void syntax_highlight_actions::span_end(parse_iterator first,
+ parse_iterator last)
     {
         while (first != last)
             detail::print_char(*first++, out.get());
         out << "</phrase>";
     }
 
- void unexpected_char::operator()(parse_iterator first, parse_iterator last) const
+ void syntax_highlight_actions::unexpected_char(parse_iterator first,
+ parse_iterator last)
     {
         file_position const pos = escape_actions.current_file->position_of(first.base());
 
@@ -155,28 +150,31 @@
         out << "</phrase>";
     }
 
- void plain_char::operator()(char ch) const
- {
- detail::print_char(ch, out.get());
- }
-
- void plain_char::operator()(parse_iterator first, parse_iterator last) const
+ void syntax_highlight_actions::plain_char(parse_iterator first,
+ parse_iterator last)
     {
         while (first != last)
             detail::print_char(*first++, out.get());
     }
 
- void pre_escape_back::operator()(parse_iterator, parse_iterator) const
+ void syntax_highlight_actions::pre_escape_back(parse_iterator,
+ parse_iterator)
     {
         escape_actions.phrase.push(); // save the stream
     }
 
- void post_escape_back::operator()(parse_iterator, parse_iterator) const
+ void syntax_highlight_actions::post_escape_back(parse_iterator,
+ parse_iterator)
     {
         out << escape_actions.phrase.str();
         escape_actions.phrase.pop(); // restore the stream
     }
 
+ void syntax_highlight_actions::do_macro(std::string const& v)
+ {
+ do_macro_impl(v);
+ }
+
     // Syntax
 
     struct keywords_holder
@@ -225,45 +223,56 @@
     }
 
     // Grammar for C++ highlighting
- struct cpp_highlight
- : public cl::grammar<cpp_highlight>
+ struct cpp_highlight : public cl::grammar<cpp_highlight>
     {
- cpp_highlight(collector& out, actions& escape_actions)
- : out(out), escape_actions(escape_actions) {}
+ cpp_highlight(syntax_highlight_actions& actions)
+ : actions(actions) {}
 
         template <typename Scanner>
         struct definition
         {
             definition(cpp_highlight const& self)
- : g(self.escape_actions.grammar())
+ : g(self.actions.escape_actions.grammar())
             {
+ member_action1<syntax_highlight_actions, char const*>
+ span(self.actions, &syntax_highlight_actions::span),
+ span_start(self.actions, &syntax_highlight_actions::span_start);
+ member_action<syntax_highlight_actions>
+ span_end(self.actions, &syntax_highlight_actions::span_end),
+ unexpected_char(self.actions, &syntax_highlight_actions::unexpected_char),
+ plain_char(self.actions, &syntax_highlight_actions::plain_char),
+ pre_escape_back(self.actions, &syntax_highlight_actions::pre_escape_back),
+ post_escape_back(self.actions, &syntax_highlight_actions::post_escape_back);
+ member_action_value<syntax_highlight_actions, std::string const&>
+ do_macro(self.actions, &syntax_highlight_actions::do_macro);
+
                 program
                     =
- *( (+cl::space_p) [plain_char(self.out)]
+ *( (+cl::space_p) [plain_char]
                     | macro
                     | escape
- | preprocessor [span("preprocessor", self.out)]
+ | preprocessor [span("preprocessor")]
                     | comment
- | keyword [span("keyword", self.out)]
- | identifier [span("identifier", self.out)]
- | special [span("special", self.out)]
- | string_ [span("string", self.out)]
- | char_ [span("char", self.out)]
- | number [span("number", self.out)]
- | cl::repeat_p(1)[cl::anychar_p]
- [unexpected_char(self.out, self.escape_actions)]
+ | keyword [span("keyword")]
+ | identifier [span("identifier")]
+ | special [span("special")]
+ | string_ [span("string")]
+ | char_ [span("char")]
+ | number [span("number")]
+ | cl::repeat_p(1)[cl::anychar_p] [unexpected_char]
                     )
                     ;
 
                 macro =
                     // must not be followed by alpha or underscore
- cl::eps_p(self.escape_actions.macro
+ cl::eps_p(self.actions.escape_actions.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
- >> self.escape_actions.macro [do_macro_action(self.out, self.escape_actions)]
+ >> self.actions.escape_actions.macro
+ [do_macro]
                     ;
 
                 escape =
- cl::str_p("``") [pre_escape_back(self.escape_actions)]
+ cl::str_p("``") [pre_escape_back]
>>
                     (
                         (
@@ -275,10 +284,10 @@
                         )
                         |
                         (
- cl::eps_p [self.escape_actions.error]
+ cl::eps_p [self.actions.escape_actions.error]
>> *cl::anychar_p
                         )
- ) [post_escape_back(self.out, self.escape_actions)]
+ ) [post_escape_back]
                     ;
 
                 preprocessor
@@ -286,18 +295,18 @@
                     ;
 
                 comment
- = cl::str_p("//") [span_start("comment", self.out)]
+ = cl::str_p("//") [span_start("comment")]
>> *( escape
                         | (+(cl::anychar_p - (cl::eol_p | "``")))
- [plain_char(self.out)]
+ [plain_char]
                         )
- >> cl::eps_p [span_end(self.out)]
- | cl::str_p("/*") [span_start("comment", self.out)]
+ >> cl::eps_p [span_end]
+ | cl::str_p("/*") [span_start("comment")]
>> *( escape
                         | (+(cl::anychar_p - (cl::str_p("*/") | "``")))
- [plain_char(self.out)]
+ [plain_char]
                         )
- >> (!cl::str_p("*/")) [span_end(self.out)]
+ >> (!cl::str_p("*/")) [span_end]
                     ;
 
                 keyword
@@ -343,50 +352,60 @@
             start() const { return program; }
         };
 
- collector& out;
- actions& escape_actions;
+ syntax_highlight_actions& actions;
     };
 
     // Grammar for Python highlighting
     // See also: The Python Reference Manual
     // http://docs.python.org/ref/ref.html
- struct python_highlight
- : public cl::grammar<python_highlight>
+ struct python_highlight : public cl::grammar<python_highlight>
     {
- python_highlight(collector& out, actions& escape_actions)
- : out(out), escape_actions(escape_actions) {}
+ python_highlight(syntax_highlight_actions& actions)
+ : actions(actions) {}
 
         template <typename Scanner>
         struct definition
         {
             definition(python_highlight const& self)
- : g(self.escape_actions.grammar())
+ : g(self.actions.escape_actions.grammar())
             {
+ member_action1<syntax_highlight_actions, char const*>
+ span(self.actions, &syntax_highlight_actions::span),
+ span_start(self.actions, &syntax_highlight_actions::span_start);
+ member_action<syntax_highlight_actions>
+ span_end(self.actions, &syntax_highlight_actions::span_end),
+ unexpected_char(self.actions, &syntax_highlight_actions::unexpected_char),
+ plain_char(self.actions, &syntax_highlight_actions::plain_char),
+ pre_escape_back(self.actions, &syntax_highlight_actions::pre_escape_back),
+ post_escape_back(self.actions, &syntax_highlight_actions::post_escape_back);
+ member_action_value<syntax_highlight_actions, std::string const&>
+ do_macro(self.actions, &syntax_highlight_actions::do_macro);
+
                 program
                     =
- *( (+cl::space_p) [plain_char(self.out)]
+ *( (+cl::space_p) [plain_char]
                     | macro
                     | escape
                     | comment
- | keyword [span("keyword", self.out)]
- | identifier [span("identifier", self.out)]
- | special [span("special", self.out)]
- | string_ [span("string", self.out)]
- | number [span("number", self.out)]
- | cl::repeat_p(1)[cl::anychar_p]
- [unexpected_char(self.out, self.escape_actions)]
+ | keyword [span("keyword")]
+ | identifier [span("identifier")]
+ | special [span("special")]
+ | string_ [span("string")]
+ | number [span("number")]
+ | cl::repeat_p(1)[cl::anychar_p] [unexpected_char]
                     )
                     ;
 
                 macro =
                     // must not be followed by alpha or underscore
- cl::eps_p(self.escape_actions.macro
+ cl::eps_p(self.actions.escape_actions.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
- >> self.escape_actions.macro [do_macro_action(self.out, self.escape_actions)]
+ >> self.actions.escape_actions.macro
+ [do_macro]
                     ;
 
                 escape =
- cl::str_p("``") [pre_escape_back(self.escape_actions)]
+ cl::str_p("``") [pre_escape_back]
>>
                     (
                         (
@@ -398,19 +417,19 @@
                         )
                         |
                         (
- cl::eps_p [self.escape_actions.error]
+ cl::eps_p [self.actions.escape_actions.error]
>> *cl::anychar_p
                         )
- ) [post_escape_back(self.out, self.escape_actions)]
+ ) [post_escape_back]
                     ;
 
                 comment
- = cl::str_p("#") [span_start("comment", self.out)]
+ = cl::str_p("#") [span_start("comment")]
>> *( escape
                         | (+(cl::anychar_p - (cl::eol_p | "``")))
- [plain_char(self.out)]
+ [plain_char]
                         )
- >> cl::eps_p [span_end(self.out)]
+ >> cl::eps_p [span_end]
                     ;
 
                 keyword
@@ -468,40 +487,46 @@
             start() const { return program; }
         };
 
- collector& out;
- actions& escape_actions;
+ syntax_highlight_actions& actions;
     };
 
     // Grammar for plain text (no actual highlighting)
- struct teletype_highlight
- : public cl::grammar<teletype_highlight>
+ struct teletype_highlight : public cl::grammar<teletype_highlight>
     {
- teletype_highlight(collector& out, actions& escape_actions)
- : out(out), escape_actions(escape_actions) {}
+ teletype_highlight(syntax_highlight_actions& actions)
+ : actions(actions) {}
 
         template <typename Scanner>
         struct definition
         {
             definition(teletype_highlight const& self)
- : g(self.escape_actions.grammar())
+ : g(self.actions.escape_actions.grammar())
             {
+ member_action<syntax_highlight_actions>
+ plain_char(self.actions, &syntax_highlight_actions::plain_char),
+ pre_escape_back(self.actions, &syntax_highlight_actions::pre_escape_back),
+ post_escape_back(self.actions, &syntax_highlight_actions::post_escape_back);
+ member_action_value<syntax_highlight_actions, std::string const&>
+ do_macro(self.actions, &syntax_highlight_actions::do_macro);
+
                 program
                     =
                     *( macro
                     | escape
- | cl::repeat_p(1)[cl::anychar_p] [plain_char(self.out)]
+ | cl::repeat_p(1)[cl::anychar_p] [plain_char]
                     )
                     ;
 
                 macro =
                     // must not be followed by alpha or underscore
- cl::eps_p(self.escape_actions.macro
+ cl::eps_p(self.actions.escape_actions.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
- >> self.escape_actions.macro [do_macro_action(self.out, self.escape_actions)]
+ >> self.actions.escape_actions.macro
+ [do_macro]
                     ;
 
                 escape =
- cl::str_p("``") [pre_escape_back(self.escape_actions)]
+ cl::str_p("``") [pre_escape_back]
>>
                     (
                         (
@@ -513,10 +538,10 @@
                         )
                         |
                         (
- cl::eps_p [self.escape_actions.error]
+ cl::eps_p [self.actions.escape_actions.error]
>> *cl::anychar_p
                         )
- ) [post_escape_back(self.out, self.escape_actions)]
+ ) [post_escape_back]
                     ;
             }
 
@@ -528,8 +553,7 @@
             start() const { return program; }
         };
 
- collector& out;
- actions& escape_actions;
+ syntax_highlight_actions& actions;
     };
 
     std::string syntax_highlight(
@@ -538,22 +562,22 @@
         actions& escape_actions,
         std::string const& source_mode)
     {
- quickbook::collector temp;
+ syntax_highlight_actions syn_actions(escape_actions);
 
         // print the code with syntax coloring
         if (source_mode == "c++")
         {
- cpp_highlight cpp_p(temp, escape_actions);
+ cpp_highlight cpp_p(syn_actions);
             boost::spirit::classic::parse(first, last, cpp_p);
         }
         else if (source_mode == "python")
         {
- python_highlight python_p(temp, escape_actions);
+ python_highlight python_p(syn_actions);
             boost::spirit::classic::parse(first, last, python_p);
         }
         else if (source_mode == "teletype")
         {
- teletype_highlight teletype_p(temp, escape_actions);
+ teletype_highlight teletype_p(syn_actions);
             boost::spirit::classic::parse(first, last, teletype_p);
         }
         else
@@ -562,7 +586,7 @@
         }
 
         std::string str;
- temp.swap(str);
+ syn_actions.out.swap(str);
         
         return str;
     }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk