Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

SyntaxParser Class Reference

#include <cmt_syntax.h>

Collaboration diagram for SyntaxParser:

Collaboration graph
[legend]
List of all members.

Static Public Member Functions

SyntaxParserinstance ()
void parse_requirements (const cmt_string &file_name, Use *use)
 Parse the input file, rejecting comments and rebuilding complete lines (from sections separated by \ characters.

void parse_project_file_text (const cmt_string &text, const cmt_string &file_name, Project *project)
void parse_requirements_text (const cmt_string &text, const cmt_string &file_name, Use *use)
 Parse a text, rejecting comments and rebuilding complete lines (from sections separated by \ characters.

void parse_requirements_line (const cmt_string &line, Use *use, const cmt_string &file_name="", int line_number=0)
 Apply the basic parser to one single line :.


Private Types

enum  ContextType { project_context, package_context }

Private Member Functions

void do_parse_requirements (const cmt_string &file_name, Use *use)
void do_parse_text (const cmt_string &text, const cmt_string &file_name, ContextType context, Use *use, Project *project)
 Parse a text, rejecting comments and rebuilding complete lines (from sections separated by \ characters.

void do_parse_line (const cmt_string &line, const cmt_string &file_name, int line_number, ContextType context, Use *use, Project *project)
void do_parse_words (const CmtSystem::cmt_string_vector &words, const cmt_string &file_name, int line_number, Use *use)
void do_parse_words (const CmtSystem::cmt_string_vector &words, const cmt_string &file_name, int line_number, Project *project)
 SyntaxParser ()

Private Attributes

cmt_map< cmt_string, Kwdm_keywords
cmt_map< cmt_string, Kwdm_project_keywords
cmt_string m_filtered_text

Member Enumeration Documentation

enum SyntaxParser::ContextType [private]
 

Enumeration values:
project_context 
package_context 

Definition at line 52 of file cmt_syntax.h.

00053     {
00054       project_context,
00055       package_context
00056     } ContextType;


Constructor & Destructor Documentation

SyntaxParser::SyntaxParser  )  [private]
 

Definition at line 1032 of file cmt_syntax.cxx.

References cmt_map< cmt_string, Kwd >::add(), m_keywords, and m_project_keywords.

01033 {
01034   m_keywords.add ("action", new KwdAction ());
01035   m_keywords.add ("alias", new KwdAlias ());
01036   m_keywords.add ("application", new KwdApplication ());
01037   m_keywords.add ("apply_pattern", new KwdApplyPattern ());
01038   m_keywords.add ("apply_tag", new KwdApplyTag ());
01039   m_keywords.add ("author", new KwdAuthor ());
01040   m_keywords.add ("branches", new KwdBranches ());
01041   m_keywords.add ("build_strategy", new KwdBuildStrategy ());
01042   m_keywords.add ("cleanup_script", new KwdCleanupScript ());
01043   m_keywords.add ("cmtpath_pattern", new KwdCmtPathPattern ());
01044   m_keywords.add ("document", new KwdDocument ());
01045   m_keywords.add ("end_private", new KwdEndPrivate ());
01046   m_keywords.add ("end_public", new KwdEndPublic ());
01047   m_keywords.add ("ignore_pattern", new KwdIgnorePattern ());
01048   m_keywords.add ("include_dirs", new KwdIncludeDirs ());
01049   m_keywords.add ("include_path", new KwdIncludePath ());
01050   m_keywords.add ("language", new KwdLanguage ());
01051   m_keywords.add ("library", new KwdLibrary ());
01052   m_keywords.add ("macro", new KwdMacro ());
01053   m_keywords.add ("macro+", new KwdMacroAppend ());
01054   m_keywords.add ("macro_prepend", new KwdMacroPrepend ());
01055   m_keywords.add ("macro_append", new KwdMacroAppend ());
01056   m_keywords.add ("macro_remove", new KwdMacroRemove ());
01057   m_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ());
01058   m_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ());
01059   m_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ());
01060   m_keywords.add ("make_fragment", new KwdMakeFragment ());
01061   m_keywords.add ("manager", new KwdManager ());
01062   m_keywords.add ("package", new KwdPackage ());
01063   m_keywords.add ("path", new KwdPath ());
01064   m_keywords.add ("path_append", new KwdPathAppend ());
01065   m_keywords.add ("path_prepend", new KwdPathPrepend ());
01066   m_keywords.add ("path_remove", new KwdPathRemove ());
01067   m_keywords.add ("path_remove_regexp", new KwdPathRemoveRegexp ());
01068   m_keywords.add ("pattern", new KwdPattern ());
01069   m_keywords.add ("public", new KwdPublic ());
01070   m_keywords.add ("private", new KwdPrivate ());
01071   m_keywords.add ("project", new KwdProject ());
01072   m_keywords.add ("set", new KwdSet ());
01073   m_keywords.add ("set_append", new KwdSetAppend ());
01074   m_keywords.add ("set_prepend", new KwdSetPrepend ());
01075   m_keywords.add ("set_remove", new KwdSetRemove ());
01076   m_keywords.add ("set_remove_regexp", new KwdSetRemoveRegexp ());
01077   m_keywords.add ("setup_script", new KwdSetupScript ());
01078   m_keywords.add ("setup_strategy", new KwdSetupStrategy ());
01079   m_keywords.add ("tag", new KwdTag ());
01080   m_keywords.add ("tag_exclude", new KwdTagExclude ());
01081   m_keywords.add ("use", new KwdUse ());
01082   m_keywords.add ("version_strategy", new KwdVersionStrategy ());
01083   m_keywords.add ("version", new KwdVersion ());
01084 
01085   m_project_keywords.add ("build_strategy", new KwdBuildStrategy ());
01086   m_project_keywords.add ("container", new KwdContainer ());
01087   m_project_keywords.add ("project", new KwdProject ());
01088   m_project_keywords.add ("setup_strategy", new KwdSetupStrategy ());
01089   m_project_keywords.add ("use", new KwdUse ());
01090 }


Member Function Documentation

void SyntaxParser::do_parse_line const cmt_string line,
const cmt_string file_name,
int  line_number,
ContextType  context,
Use use,
Project project
[private]
 

Definition at line 1203 of file cmt_syntax.cxx.

References CmtSystem::cmt_string_vector, do_parse_words(), cmt_string::erase(), cmt_string::find_last_of(), Cmt::get_debug(), m_filtered_text, package_context, project_context, cmt_string::replace_all(), cmt_vector< T >::size(), cmt_string::size(), and CmtSystem::split().

Referenced by do_parse_text(), and parse_requirements_line().

01209 {
01210   int length;
01211   int nl;
01212   int back_slash;
01213   cmt_string temp_line = line;
01214 
01215   if (temp_line.size () == 0) return;
01216   if (temp_line[0] == '#') return;
01217 
01218   nl = temp_line.find_last_of ('\n');
01219   if (nl != cmt_string::npos) temp_line.erase (nl);
01220 
01221   length = temp_line.size ();
01222   if (length == 0) return;
01223 
01224   //
01225   // We scan the line for handling backslashes.
01226   //
01227   // o Really terminating backslashes (ie those only followed by spaces/tabs
01228   // mean continued line
01229   //
01230   //
01231 
01232   bool finished = true;
01233 
01234   length = temp_line.size ();
01235 
01236   back_slash = temp_line.find_last_of ('\\');
01237 
01238   if (back_slash != cmt_string::npos)
01239     {
01240       //
01241       // This is the last backslash
01242       // check if there are only space chars after it
01243       //
01244       
01245       bool at_end = true;
01246 
01247       for (int i = (back_slash + 1); i < length; i++)
01248         {
01249           char c = temp_line[i];
01250           if ((c != ' ') && (c != '\t'))
01251             {
01252               at_end = false;
01253               break;
01254             }
01255         }
01256 
01257       if (at_end)
01258         {
01259           temp_line.erase (back_slash);
01260           finished = false;
01261         }
01262       else
01263         {
01264           // This was not a trailing backslash.
01265           finished = true;
01266         }
01267     }
01268 
01269   m_filtered_text += temp_line;
01270 
01271   if (!finished)
01272     {
01273       // We still need to accumulate forthcoming lines
01274       // before parsing the resulting text.
01275       return;
01276     }
01277 
01278   /*
01279     Here a full line (possibly accumulating several lines
01280     ended by backslashes) is parsed :
01281     
01282     o Special characters are filtered now :
01283     
01284     <cmt:tab/>  \t
01285     <cmt:cr/>   \r
01286     <cmt:lf/>   \n
01287     
01288     o Split into words (a word is a string not containing
01289     spaces or enclosed in quotes)
01290 
01291     o Parse the word array (function Select)
01292 
01293   */
01294 
01295   m_filtered_text.replace_all ("<cmt:tab/>", "\t");
01296   m_filtered_text.replace_all ("<cmt:cr/>",  "\r");
01297   m_filtered_text.replace_all ("<cmt:lf/>",  "\n");
01298 
01299   if (Cmt::get_debug ())
01300     {
01301       cout << "parse_requirements_line [" << m_filtered_text << "]" << endl;
01302     }
01303   
01304   static CmtSystem::cmt_string_vector words;
01305   
01306   CmtSystem::split (m_filtered_text, " \t", words);
01307   
01308   if (words.size () != 0)
01309     {
01310       switch (context)
01311         {
01312         case project_context:
01313           do_parse_words (words, file_name, line_number, project);
01314           break;
01315         case package_context:
01316           do_parse_words (words, file_name, line_number, use);
01317           break;
01318         }
01319     }
01320   
01321   m_filtered_text.erase (0);
01322 }

void SyntaxParser::do_parse_requirements const cmt_string file_name,
Use use
[private]
 

Definition at line 1092 of file cmt_syntax.cxx.

References CmtError::clear(), CmtSystem::file_separator(), parse_requirements_text(), cmt_string::read(), and CmtSystem::test_file().

Referenced by parse_requirements().

01093 {
01094   cmt_string actual_file_name = file_name;
01095   cmt_string text;
01096 
01097   CmtError::clear ();
01098 
01099   if (!CmtSystem::test_file (actual_file_name))
01100     {
01101       actual_file_name = "..";
01102       actual_file_name += CmtSystem::file_separator ();
01103       actual_file_name += "cmt";
01104       actual_file_name += CmtSystem::file_separator ();
01105       actual_file_name += file_name;
01106 
01107       if (!CmtSystem::test_file (actual_file_name))
01108         {
01109           actual_file_name = "..";
01110           actual_file_name += CmtSystem::file_separator ();
01111           actual_file_name += "mgr";
01112           actual_file_name += CmtSystem::file_separator ();
01113           actual_file_name += file_name;
01114 
01115           if (!CmtSystem::test_file (actual_file_name))
01116             {
01117               return;
01118             }
01119         }
01120     }
01121 
01122   text.read (actual_file_name);
01123 
01124   SyntaxParser::parse_requirements_text (text, actual_file_name, use);
01125 }

void SyntaxParser::do_parse_text const cmt_string text,
const cmt_string file_name,
ContextType  context,
Use use,
Project project
[private]
 

Parse a text, rejecting comments and rebuilding complete lines (from sections separated by \ characters.

Each reformatted line is parsed by filter_line

Definition at line 1134 of file cmt_syntax.cxx.

References action_check_configuration, Use::current(), do_parse_line(), cmt_string::erase(), cmt_string::find(), Cmt::get_action(), CmtError::has_pending_error(), m_filtered_text, package_context, cmt_string::size(), and cmt_string::substr().

Referenced by parse_project_file_text(), parse_requirements(), and parse_requirements_text().

01139 {
01140   cmt_string line;
01141   int pos;
01142   int max_pos;
01143   int line_number = 1;
01144 
01145   if (context == package_context)
01146     {
01147       if (use == 0) use = &(Use::current ());
01148     }
01149 
01150   m_filtered_text.erase (0);
01151 
01152   pos = 0;
01153   max_pos = text.size ();
01154 
01155   for (pos = 0; pos < max_pos;)
01156     {
01157       int cr = text.find (pos, "\r\n");
01158       int nl = text.find (pos, '\n');
01159       int first = nl;
01160       int length = 1;
01161 
01162       if (cr != cmt_string::npos)
01163         {
01164           if (nl == cmt_string::npos)
01165             {
01166               first = cr;
01167               length = 2;
01168             }
01169           else
01170             {
01171               first = (nl < cr) ? nl : cr;
01172               length = (nl < cr) ? 1 : 2;
01173             }
01174         }
01175 
01176       if (first == cmt_string::npos)
01177         {
01178           text.substr (pos, line);
01179           pos = max_pos;
01180         }
01181       else if (first > pos)
01182         {
01183           text.substr (pos, first - pos, line);
01184           pos = first + length;
01185         }
01186       else
01187         {
01188           line.erase (0);
01189           pos += length;
01190         }
01191 
01192       do_parse_line (line, file_name, line_number, context, use, project);
01193 
01194       if ((Cmt::get_action () == action_check_configuration) && CmtError::has_pending_error ())
01195         {
01196           //break;
01197         }
01198 
01199       line_number++;
01200     }
01201 }

void SyntaxParser::do_parse_words const CmtSystem::cmt_string_vector words,
const cmt_string file_name,
int  line_number,
Project project
[private]
 

Definition at line 1383 of file cmt_syntax.cxx.

References Kwd::action(), CmtError::clear(), CmtSystem::cmt_string_vector, cmt_map< cmt_string, Kwd >::find(), Project::get_name(), Cmt::get_quiet(), CmtError::has_pending_error(), m_project_keywords, CmtError::set(), cmt_string::size(), and cmt_vector< T >::size().

01387 {
01388   CmtError::clear ();
01389 
01390   if (words.size () == 0) return;
01391 
01392   const cmt_string& command = words[0];
01393 
01394   if (command.size () == 0) return;
01395 
01396   //
01397   // First analyze the syntax
01398   //
01399 
01400   Kwd* keyword = m_project_keywords.find (command);
01401   if (keyword == 0)
01402     {
01403       CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
01404     }
01405 
01406   if (CmtError::has_pending_error ())
01407     {
01408       if (!Cmt::get_quiet ())
01409         {
01410           cerr << "#CMT> bad syntax in project file of " << project->get_name ()
01411                << " line #" << line_number;
01412           cerr << " [" << command << " ...]" << endl;
01413         }
01414 
01415       return;
01416     }
01417 
01418   //
01419   // Then interpret the action
01420   //
01421 
01422   keyword->action (words, project, file_name, line_number);
01423 }

void SyntaxParser::do_parse_words const CmtSystem::cmt_string_vector words,
const cmt_string file_name,
int  line_number,
Use use
[private]
 

Definition at line 1324 of file cmt_syntax.cxx.

References Kwd::action(), CmtError::clear(), CmtSystem::cmt_string_vector, Pattern::find(), cmt_map< cmt_string, Kwd >::find(), Use::get_package_name(), Cmt::get_quiet(), CmtError::has_pending_error(), m_keywords, CmtError::set(), cmt_string::size(), cmt_vector< T >::size(), Use::specified_path, and Use::version.

Referenced by do_parse_line().

01328 {
01329   CmtError::clear ();
01330 
01331   if (words.size () == 0) return;
01332 
01333   const cmt_string& command = words[0];
01334 
01335   if (command.size () == 0) return;
01336 
01337   //
01338   // First analyze the syntax
01339   //
01340 
01341   Kwd* keyword = m_keywords.find (command);
01342   if (keyword == 0)
01343     {
01344       /*
01345 
01346         When the first word of the line is not a keyword, it may be an
01347         implicit pattern application.
01348 
01349        */
01350 
01351       Pattern* p = Pattern::find (command);
01352       if (p == 0)
01353         {
01354           CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
01355         }
01356       else
01357         {
01358           keyword = m_keywords.find ("apply_pattern");
01359         }
01360     }
01361 
01362   if (CmtError::has_pending_error ())
01363     {
01364       if (!Cmt::get_quiet ())
01365         {
01366           cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
01367                << " " << use->version 
01368                << " " << use->specified_path 
01369                << " line #" << line_number;
01370           cerr << " [" << command << " ...]" << endl;
01371         }
01372 
01373       return;
01374     }
01375 
01376   //
01377   // Then interpret the action
01378   //
01379 
01380   keyword->action (words, use, file_name, line_number);
01381 }

SyntaxParser & SyntaxParser::instance  )  [static]
 

Definition at line 906 of file cmt_syntax.cxx.

Referenced by parse_project_file_text(), parse_requirements(), parse_requirements_line(), and parse_requirements_text().

00907 {
00908   static SyntaxParser p;
00909 
00910   return (p);
00911 }

void SyntaxParser::parse_project_file_text const cmt_string text,
const cmt_string file_name,
Project project
[static]
 

Definition at line 946 of file cmt_syntax.cxx.

References do_parse_text(), instance(), and project_context.

Referenced by ProjectFactory::create_project().

00949 {
00950   SyntaxParser& me = instance ();
00951   me.do_parse_text (text, file_name, project_context, 0, project);
00952 }

void SyntaxParser::parse_requirements const cmt_string file_name,
Use use
[static]
 

Parse the input file, rejecting comments and rebuilding complete lines (from sections separated by \ characters.

Each reformatted line is parsed by filter_line

Definition at line 920 of file cmt_syntax.cxx.

References AccessMode, Use::close_scope_sections(), do_parse_requirements(), do_parse_text(), Use::fill_standard_macros(), Cmt::get_current_access(), instance(), package_context, Cmt::set_current_access(), and UserMode.

Referenced by Use::add(), Cmt::load(), Cmt::parser(), Cmt::reach_current_package(), and Cmt::use_special_requirements().

00921 {
00922   SyntaxParser& me = instance ();
00923 
00924   if (use != 0)
00925     {
00926       cmt_string buffer;
00927 
00928       use->fill_standard_macros (buffer);
00929 
00930       AccessMode saved_current_access = Cmt::get_current_access ();
00931       Cmt::set_current_access (UserMode);
00932       me.do_parse_text (buffer, "", package_context, use, 0);
00933       Cmt::set_current_access (saved_current_access);
00934     }
00935 
00936   me.do_parse_requirements (file_name, use);
00937 
00938   if (use != 0)
00939     {
00940       use->close_scope_sections ();
00941     }
00942 }

void SyntaxParser::parse_requirements_line const cmt_string line,
Use use,
const cmt_string file_name = "",
int  line_number = 0
[static]
 

Apply the basic parser to one single line :.

o Append to global text if previous back_slash o Split into words o Apply the generic Select operator

Definition at line 1023 of file cmt_syntax.cxx.

References do_parse_line(), instance(), and package_context.

Referenced by StandardMacroBuilder::apply(), Cmt::do_do(), StandardMacroBuilder::fill_for_constituent_macros(), Cmt::parser(), and CmtInstallAreaMgr::setup_current_installarea().

01027 {
01028   SyntaxParser& me = instance ();
01029   me.do_parse_line (line, file_name, line_number, package_context, use, 0);
01030 }

void SyntaxParser::parse_requirements_text const cmt_string text,
const cmt_string file_name,
Use use
[static]
 

Parse a text, rejecting comments and rebuilding complete lines (from sections separated by \ characters.

Each reformatted line is parsed by filter_line

We have to preserve m_current_access since it reflects whether the current cmt action is run in the context of the current package. (the opposite is when the cmt command specifies the current package in its arguments -use=... therefore the pwd is NOT the directory of the current package)

m_current_access is Developer when pwd = current User when pwd != current

Therefore, as soon as we reach a used package, this must be switched to User

On the other hand, Cmt::scope reflects the status of the public/private statements. By default, we are in public context when entering a new requirements file.

Definition at line 961 of file cmt_syntax.cxx.

References AccessMode, Use::current(), DeveloperMode, do_parse_text(), Cmt::get_current_access(), Cmt::get_debug(), instance(), package_context, Cmt::set_current_access(), and UserMode.

Referenced by Pattern::apply(), CmtPathPattern::apply(), do_parse_requirements(), ApplicationAnalyzer::end(), LibraryAnalyzer::end(), Cmt::guess_current_project(), and CmtPathPatternProjectAction::run().

00964 {
00965   SyntaxParser& me = instance ();
00966 
00986   AccessMode saved_current_access;
00987 
00988   saved_current_access = Cmt::get_current_access ();
00989 
00990   if (use == 0) use = &(Use::current ());
00991 
00992   if (use != &(Use::current ()))
00993     {
00994       if (Cmt::get_debug ())
00995         {
00996           cout << "parse_requirements_text> set UserMode" << endl;
00997         }
00998 
00999       Cmt::set_current_access (UserMode);
01000     }
01001   else
01002     {
01003       if (Cmt::get_debug ())
01004         {
01005           cout << "parse_requirements_text> set DeveloperMode" << endl;
01006         }
01007 
01008       Cmt::set_current_access (DeveloperMode);
01009     }
01010 
01011   me.do_parse_text (text, file_name, package_context, use, 0);
01012 
01013   Cmt::set_current_access (saved_current_access);
01014 }


Member Data Documentation

cmt_string SyntaxParser::m_filtered_text [private]
 

Definition at line 86 of file cmt_syntax.h.

Referenced by do_parse_line(), and do_parse_text().

cmt_map<cmt_string, Kwd> SyntaxParser::m_keywords [private]
 

Definition at line 84 of file cmt_syntax.h.

Referenced by do_parse_words(), and SyntaxParser().

cmt_map<cmt_string, Kwd> SyntaxParser::m_project_keywords [private]
 

Definition at line 85 of file cmt_syntax.h.

Referenced by do_parse_words(), and SyntaxParser().


The documentation for this class was generated from the following files:
Generated on Mon May 2 10:26:03 2005 for CMT by doxygen 1.3.5