[Xorp-hackers] [PATCH 10/10] xorp: Automatically generate lex and yacc files

igorm at etf.rs igorm at etf.rs
Tue Mar 13 03:39:43 PDT 2012


From: Igor Maravic <igorm at etf.rs>

In xorp/site_scons/config/allconfig.py added checks if 'flex' and 'bison' are installed.
If they aren't instructs user how to install them (instructions are for Ubuntu and Fedora).

Change xorp/rtrmgr/SConscript to automatically generate yacc and lex files with bison and flex.
In CPPPATH added env['xorp_sorcedir'] so generated files could include necessary files.
Also did minor changes in .yy and .ll files, so they would compile.

Unfortunately Eclipse striped whitespaces from changed files, so they are meshed up with the changed code.

Signed-off-by: Igor Maravic <igorm at etf.rs>
---
 xorp/rtrmgr/SConscript              |   79 +++++++++++++++------
 xorp/rtrmgr/boot.ll                 |    6 +-
 xorp/rtrmgr/boot.yy                 |   64 ++++++++++++-----
 xorp/rtrmgr/op_commands.cc          |    8 +-
 xorp/rtrmgr/op_commands.ll          |    4 +-
 xorp/rtrmgr/op_commands.yy          |  132 +++++++++++++++++++++++++----------
 xorp/rtrmgr/template.ll             |    4 +-
 xorp/rtrmgr/template.yy             |   97 ++++++++++++++++++-------
 xorp/site_scons/config/allconfig.py |   15 ++++
 9 files changed, 295 insertions(+), 114 deletions(-)

diff --git a/xorp/rtrmgr/SConscript b/xorp/rtrmgr/SConscript
index adf2f1c..ebe930c 100644
--- a/xorp/rtrmgr/SConscript
+++ b/xorp/rtrmgr/SConscript
@@ -30,9 +30,10 @@ SConscript(dirs = subdirs, exports='env')
 env = env.Clone()
 
 env.AppendUnique(CPPPATH = [
-    '#',
-    '$BUILDDIR',
-    ])
+	'.',
+	'$BUILDDIR',
+	env['xorp_sourcedir'],	#this is needed for lex and yacc generated files
+	])
 
 env.PrependUnique(LIBPATH = [
     '$BUILDDIR/libxorp',
@@ -50,20 +51,52 @@ env.PrependUnique(LIBPATH = [
 
 libxorp_rtrmgr_env = env.Clone()
 
-# FIXME generate lex/yacc from source
-# shorthand this plz
-# see http://209.85.229.132/search?q=cache:3j0AsRORc6MJ:https://gforge.inria.fr/plugins/scmsvn/viewcvs.php/scons_util/trunk/src/platform.py%3Frev%3D18%26root%3Dopenalea%26view%3Dmarkup+scons+lexflags+append&cd=2&hl=en&ct=clnk&gl=uk&client=firefox-a
-# ... needs toolchain check for flex 2.5.4 or poss more recent.
-# known to work with freebsd base system flex.
-#tplt_env = env.Clone()
-#tplt_env.AppendUnique(LEXFLAGS='-Ptplt')
-#tplt_env.CXXFile(source='template.ll', target='lex.tplt.cc')
-#boot_env = env.Clone()
-#boot_env.AppendUnique(LEXFLAGS='-Pboot')
-#boot_env.CXXFile(source='boot.ll', target='lex.boot.cc')
-#opcmd_env = env.Clone()
-#opcmd_env.AppendUnique(LEXFLAGS='-Popcmd')
-#opcmd_env.CXXFile(source='op_commands.ll', target='lex.opcmd.cc')
+# Automatically generate flex and yacc files
+
+#Create yacc files
+yacc_env = env.Clone()
+yacc_env.Replace(YACCHXXFILESUFFIX='.hh')
+yacc_env.AppendUnique(YACCFLAGS='-d')
+
+
+tplt_env_y = yacc_env.Clone()
+tplt_env_y.AppendUnique(YACCFLAGS='-ptplt')
+
+tplt_yacc = tplt_env_y.CXXFile(target='y.tplt_tab.cc',
+				source='template.yy')
+
+boot_env_y = yacc_env.Clone()
+boot_env_y.AppendUnique(YACCFLAGS='-pboot')
+
+boot_yacc = boot_env_y.CXXFile(target='y.boot_tab.cc',
+					source='boot.yy')
+
+opcmd_env_y = yacc_env.Clone()
+opcmd_env_y.AppendUnique(YACCFLAGS='-popcmd')
+
+opcmd_yacc = opcmd_env_y.CXXFile(target='y.opcmd_tab.cc',
+					source='op_commands.yy')
+
+#create lex files
+lex_env = env.Clone()
+
+tplt_env_l = lex_env.Clone()
+tplt_env_l.AppendUnique(LEXFLAGS='-Ptplt')
+
+tplt_lex = tplt_env_l.CXXFile(target='lex.tplt.cc',
+					source='template.ll')
+
+boot_env_l = lex_env.Clone()
+boot_env_l.AppendUnique(LEXFLAGS='-Pboot')
+
+boot_lex = boot_env_l.CXXFile(target='lex.boot.cc',
+					source='boot.ll')
+
+opcmd_env_l = lex_env.Clone()
+opcmd_env_l.AppendUnique(LEXFLAGS='-Popcmd')
+
+opcmd_lex = opcmd_env_l.CXXFile(target='lex.opcmd.cc',
+					source='op_commands.ll')
 
 libxorp_rtrmgr_srcs = [
 	'command_tree.cc',
@@ -72,9 +105,12 @@ libxorp_rtrmgr_srcs = [
 	'config_operators.cc',
 	'generic_module_manager.cc',
 	'glob_win32.c',
-	'lex.boot.cc',
-	'lex.opcmd.cc',
-	'lex.tplt.cc',
+	tplt_lex[0],
+	opcmd_lex[0],
+	boot_lex[0],
+	opcmd_yacc[0],
+	boot_yacc[0],
+	tplt_yacc[0],
 	'master_conf_tree.cc',
 	'master_conf_tree_node.cc',
 	'master_template_tree.cc',
@@ -95,9 +131,6 @@ libxorp_rtrmgr_srcs = [
 	'unexpanded_xrl.cc',
 	'userdb.cc',
 	'xorp_client.cc',
-	'y.boot_tab.cc',
-	'y.opcmd_tab.cc',
-	'y.tplt_tab.cc',
 	]
 
 # Runtime XRL syntax validation for developers.
diff --git a/xorp/rtrmgr/boot.ll b/xorp/rtrmgr/boot.ll
index 6ea8991..3f1d5c4 100644
--- a/xorp/rtrmgr/boot.ll
+++ b/xorp/rtrmgr/boot.ll
@@ -9,16 +9,18 @@
 #undef __unused
 #endif
 
+#define YYSTYPE char*
+
 #include "libxorp/xorp.h"
-#include "y.boot_tab.h"
+#include "y.boot_tab.hh"
 
 #ifdef __xorp_unused
 #define __unused __xorp_unused
 #undef __xorp_unused
 #endif
+
 %}
 	int boot_linenum = 1;
-	extern char* bootlval;
 	string parsebuf;
 	int arith_nesting;
 	bool arith_op_allowed;
diff --git a/xorp/rtrmgr/boot.yy b/xorp/rtrmgr/boot.yy
index 6fb5939..f815477 100644
--- a/xorp/rtrmgr/boot.yy
+++ b/xorp/rtrmgr/boot.yy
@@ -18,6 +18,49 @@
 /* XXX: sigh - -p flag to yacc should do this for us */
 #define yystacksize bootstacksize
 #define yysslim bootsslim
+
+/**
+ * Forward declarations
+ */
+extern void boot_scan_string(const char *configuration);
+extern int boot_linenum;
+extern "C" int bootparse();
+extern int bootlex();
+
+void booterror(const char *s) throw (ParseError);
+
+static ConfigTree *config_tree = NULL;
+static string boot_filename;
+static string lastsymbol;
+static string node_id;
+
+/**
+ * Function declarations
+ */
+static void
+extend_path(char* segment, int type, const string& node_id_str);
+
+static void
+push_path();
+
+static void
+pop_path();
+
+static void
+terminal(char* value, int type, ConfigOperator op);
+
+void
+booterror(const char *s) throw (ParseError);
+
+int
+init_bootfile_parser(const char *configuration,
+		     const char *filename,
+		     ConfigTree *ct);
+
+void
+parse_bootfile() throw (ParseError);
+
+ConfigOperator boot_lookup_operator(const char* s);
 %}
 
 %token UPLEVEL
@@ -190,20 +233,7 @@ syntax_error:	SYNTAX_ERROR {
 
 %%
 
-extern void boot_scan_string(const char *configuration);
-extern int boot_linenum;
-extern "C" int bootparse();
-extern int bootlex();
-
-void booterror(const char *s) throw (ParseError);
-
-static ConfigTree *config_tree = NULL;
-static string boot_filename;
-static string lastsymbol;
-static string node_id;
-
-
-static void
+void
 extend_path(char* segment, int type, const string& node_id_str)
 {
     lastsymbol = segment;
@@ -221,19 +251,19 @@ extend_path(char* segment, int type, const string& node_id_str)
     }
 }
 
-static void
+void
 push_path()
 {
     config_tree->push_path();
 }
 
-static void
+void
 pop_path()
 {
     config_tree->pop_path();
 }
 
-static void
+void
 terminal(char* value, int type, ConfigOperator op)
 {
     push_path();
diff --git a/xorp/rtrmgr/op_commands.cc b/xorp/rtrmgr/op_commands.cc
index a169714..10c48c3 100644
--- a/xorp/rtrmgr/op_commands.cc
+++ b/xorp/rtrmgr/op_commands.cc
@@ -7,13 +7,13 @@
 // 1991 as published by the Free Software Foundation. Redistribution
 // and/or modification of this program under the terms of any other
 // version of the GNU General Public License is not permitted.
-// 
+//
 // This program is distributed in the hope that it will be useful, but
 // WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
 // see the GNU General Public License, Version 2, a copy of which can be
 // found in the XORP LICENSE.gpl file.
-// 
+//
 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
 // http://xorp.net
 
@@ -48,7 +48,7 @@
 #include "slave_conf_tree.hh"
 #include "template_tree.hh"
 #include "slave_module_manager.hh"
-#include "y.opcmd_tab.h"
+#include "y.opcmd_tab.hh"
 
 
 #ifdef HOST_OS_WINDOWS
@@ -358,7 +358,7 @@ OpCommand::execute(EventLoop& eventloop, const list<string>& command_line,
 					_command_executable_filename,
 					resolved_command_argument_list,
 					print_cb, done_cb);
-    
+
     return opinst;
 }
 
diff --git a/xorp/rtrmgr/op_commands.ll b/xorp/rtrmgr/op_commands.ll
index d3faae7..765cf6c 100644
--- a/xorp/rtrmgr/op_commands.ll
+++ b/xorp/rtrmgr/op_commands.ll
@@ -9,9 +9,10 @@
 #undef __unused
 #endif
 
+#define YYSTYPE char*
 #include "libxorp/xorp.h"
 #include <string.h>
-#include "y.opcmd_tab.h"
+#include "y.opcmd_tab.hh"
 
 #ifdef __xorp_unused
 #define __unused __xorp_unused
@@ -19,7 +20,6 @@
 #endif
 %}
 	int opcmd_linenum = 1;
-	extern char* opcmdlval;
 	string opcmd_parsebuf;
 %option noyywrap
 %option nounput
diff --git a/xorp/rtrmgr/op_commands.yy b/xorp/rtrmgr/op_commands.yy
index 0eb653f..63cdfa1 100644
--- a/xorp/rtrmgr/op_commands.yy
+++ b/xorp/rtrmgr/op_commands.yy
@@ -3,6 +3,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <string>
 
 #include <map>
 
@@ -17,6 +18,86 @@
 /* XXX: sigh - -p flag to yacc should do this for us */
 #define yystacksize opcmdstacksize
 #define yysslim opcmdsslim
+
+/**
+ * Forward declarations
+ */
+extern "C" int opcmdparse();
+extern int opcmdlex();
+extern FILE *opcmdin;
+extern int opcmd_linenum;
+
+void opcmderror(const char *s) throw (ParseError);
+void opcmd_warning(const char *s);
+
+static OpCommandList *ocl = NULL;
+static list<string> path_segments;
+static list<list<string> >path_segments_stack;
+static list<OpCommand> op_command_stack;
+static list<string> op_command_tag_help_stack;
+static list<map<string, string> > opt_params_tag_help_stack;
+static list<map<string, string> > tags_stack;
+static bool is_help_tag = false;
+static string help_tag;
+static string help_string;
+
+static string opcmd_filename;
+static string lastsymbol;
+
+/**
+ * Function declarations
+ */
+static string
+strip_quotes_and_empty_space(const string& s);
+
+static void
+resolve_tag(const string& tag, string& value);
+
+static void
+append_path_word(char *s);
+
+static void
+append_path_variable(char *s);
+
+static void
+push_path();
+
+static void
+pop_path();
+
+static void
+add_cmd_module(char *s);
+
+static void
+add_cmd_command(char *s);
+
+static void
+add_cmd_opt_parameter(char *s);
+
+static void
+add_cmd_tag(char *t, char *v);
+
+static void
+add_cmd_help_tag(char *s);
+
+static void
+add_cmd_help_string(char *s);
+
+static void
+set_nomore_mode(bool v);
+
+void
+opcmderror(const char *s) throw (ParseError);
+
+void
+opcmd_warning(const char *s);
+
+int
+init_opcmd_parser(const char *filename, OpCommandList *o);
+
+void
+parse_opcmd() throw (ParseError);
+
 %}
 
 %token UPLEVEL
@@ -123,31 +204,8 @@ syntax_error:		SYNTAX_ERROR { opcmderror("syntax error"); }
 
 %%
 
-extern "C" int opcmdparse();
-extern int opcmdlex();
-extern FILE *opcmdin;
-extern int opcmd_linenum;
-
-void opcmderror(const char *s) throw (ParseError);
-void opcmd_warning(const char *s);
-
-static OpCommandList *ocl = NULL;
-static list<string> path_segments;
-static list<list<string> >path_segments_stack;
-static list<OpCommand> op_command_stack;
-static list<string> op_command_tag_help_stack;
-static list<map<string, string> > opt_params_tag_help_stack;
-static list<map<string, string> > tags_stack;
-static bool is_help_tag = false;
-static string help_tag;
-static string help_string;
-
-static string opcmd_filename;
-static string lastsymbol;
-
-
 // Strip the quotes, the heading and trailing empty space
-static string
+string
 strip_quotes_and_empty_space(const string& s)
 {
     string res;
@@ -167,7 +225,7 @@ strip_quotes_and_empty_space(const string& s)
     return res;
 }
 
-static void
+void
 resolve_tag(const string& tag, string& value)
 {
     map<string, string>& tags = tags_stack.back();
@@ -182,7 +240,7 @@ resolve_tag(const string& tag, string& value)
     value = iter->second;
 }
 
-static void
+void
 append_path_word(char *s)
 {
     string word = s;
@@ -192,7 +250,7 @@ append_path_word(char *s)
     path_segments.push_back(word);
 }
 
-static void
+void
 append_path_variable(char *s)
 {
     string variable = s;
@@ -207,7 +265,7 @@ append_path_variable(char *s)
     path_segments.push_back(variable);
 }
 
-static void
+void
 push_path()
 {
     if (! path_segments_stack.empty()) {
@@ -234,7 +292,7 @@ push_path()
     tags_stack.push_back(dummy_map);
 }
 
-static void
+void
 pop_path()
 {
     string help;
@@ -283,7 +341,7 @@ pop_path()
     tags_stack.pop_back();
 }
 
-static void
+void
 add_cmd_module(char *s)
 {
     string module = s;
@@ -300,7 +358,7 @@ add_cmd_module(char *s)
     op_command.set_module(module);
 }
 
-static void
+void
 add_cmd_command(char *s)
 {
     string command = s;
@@ -404,7 +462,7 @@ add_cmd_command(char *s)
     op_command.set_help_string(help_string);
 }
 
-static void
+void
 add_cmd_opt_parameter(char *s)
 {
     string opt_parameter = s;
@@ -434,7 +492,7 @@ add_cmd_opt_parameter(char *s)
     op_command.add_opt_param(opt_parameter, help_string);
 }
 
-static void
+void
 add_cmd_tag(char *t, char *v)
 {
     string tag = t;
@@ -455,7 +513,7 @@ add_cmd_tag(char *t, char *v)
     tags.insert(make_pair(tag, value));
 }
 
-static void
+void
 add_cmd_help_tag(char *s)
 {
     string tag = s;
@@ -466,7 +524,7 @@ add_cmd_help_tag(char *s)
     is_help_tag = true;
 }
 
-static void
+void
 add_cmd_help_string(char *s)
 {
     string help = s;
@@ -480,11 +538,11 @@ add_cmd_help_string(char *s)
     is_help_tag = false;
 }
 
-static void
+void
 set_nomore_mode(bool v)
 {
     OpCommand& op_command = op_command_stack.back();
-    op_command.set_default_nomore_mode(v);    
+    op_command.set_default_nomore_mode(v);
 }
 
 void
diff --git a/xorp/rtrmgr/template.ll b/xorp/rtrmgr/template.ll
index 7361530..abcb2aa 100644
--- a/xorp/rtrmgr/template.ll
+++ b/xorp/rtrmgr/template.ll
@@ -9,8 +9,9 @@
 #undef __unused
 #endif
 
+#define YYSTYPE char*
 #include "libxorp/xorp.h"
-#include "y.tplt_tab.h"
+#include "y.tplt_tab.hh"
 
 #ifdef __xorp_unused
 #define __unused __xorp_unused
@@ -18,7 +19,6 @@
 #endif
 %}
 	int tplt_linenum = 1;
-	extern char* tpltlval;
 	string tplt_parsebuf;
 %option noyywrap
 %option nounput
diff --git a/xorp/rtrmgr/template.yy b/xorp/rtrmgr/template.yy
index c0b9747..9eadafe 100644
--- a/xorp/rtrmgr/template.yy
+++ b/xorp/rtrmgr/template.yy
@@ -18,6 +18,68 @@ extern void add_cmd_action_adaptor(const string& cmd,
 /* XXX: sigh, the -p flag to yacc should do this for us */
 #define yystacksize tpltstacksize
 #define yysslim tpltsslim
+
+/**
+ * Forward declarations
+ */
+extern char *lstr;
+extern char *vstr;
+extern char *cstr;
+extern char *sstr;
+extern char *istr;
+extern FILE *tpltin;
+extern int tplt_linenum;
+extern "C" int tpltparse();
+extern int tpltlex();
+
+static TemplateTree* tt = NULL;
+static string tplt_filename;
+static string lastsymbol;
+static int tplt_type;
+static char *tplt_initializer = NULL;
+static string current_cmd;
+static list<string> cmd_list;
+
+/**
+ * Function declarations
+ */
+
+static void
+extend_path(char *segment, bool is_tag);
+
+static void
+push_path();
+
+static void
+pop_path();
+
+static void
+terminal(char *segment);
+
+static void
+add_cmd(char *cmd);
+
+static void
+append_cmd(char *s);
+
+static void
+prepend_cmd(char *s);
+
+static void
+end_cmd();
+
+void
+tplterror(const char *s) throw (ParseError);
+
+int
+init_template_parser(const char *filename, TemplateTree *c);
+
+void
+complete_template_parser();
+
+void
+parse_template() throw (ParseError);
+
 %}
 
 %token UPLEVEL
@@ -291,26 +353,7 @@ syntax_error:	SYNTAX_ERROR {
 
 %%
 
-extern char *lstr;
-extern char *vstr;
-extern char *cstr;
-extern char *sstr;
-extern char *istr;
-extern FILE *tpltin;
-extern int tplt_linenum;
-extern "C" int tpltparse();
-extern int tpltlex();
-
-static TemplateTree* tt = NULL;
-static string tplt_filename;
-static string lastsymbol;
-static int tplt_type;
-static char *tplt_initializer = NULL;
-static string current_cmd;
-static list<string> cmd_list;
-
-
-static void
+void
 extend_path(char *segment, bool is_tag)
 {
     lastsymbol = segment;
@@ -321,7 +364,7 @@ extend_path(char *segment, bool is_tag)
     free(segment);
 }
 
-static void
+void
 push_path()
 {
     tt->push_path(tplt_type, tplt_initializer);
@@ -332,7 +375,7 @@ push_path()
     }
 }
 
-static void
+void
 pop_path()
 {
     tt->pop_path();
@@ -343,7 +386,7 @@ pop_path()
     }
 }
 
-static void
+void
 terminal(char *segment)
 {
     extend_path(segment, false);
@@ -351,7 +394,7 @@ terminal(char *segment)
     pop_path();
 }
 
-static void
+void
 add_cmd(char *cmd)
 {
     lastsymbol = cmd;
@@ -362,7 +405,7 @@ add_cmd(char *cmd)
     cmd_list.clear();
 }
 
-static void
+void
 append_cmd(char *s)
 {
     lastsymbol = s;
@@ -371,7 +414,7 @@ append_cmd(char *s)
     free(s);
 }
 
-static void
+void
 prepend_cmd(char *s)
 {
     lastsymbol = s;
@@ -380,7 +423,7 @@ prepend_cmd(char *s)
     free(s);
 }
 
-static void
+void
 end_cmd()
 {
     add_cmd_action_adaptor(current_cmd, cmd_list, tt);
diff --git a/xorp/site_scons/config/allconfig.py b/xorp/site_scons/config/allconfig.py
index f90f6ae..60f4a24 100644
--- a/xorp/site_scons/config/allconfig.py
+++ b/xorp/site_scons/config/allconfig.py
@@ -56,6 +56,21 @@ def DoAllConfig(env, conf, host_os):
         print "  existence of gcc and g++ compilers."
         print "  Will assume the exist and function properly...\n"
 
+    # Check for Flex and Bison
+    if not (env.has_key('LEX') and env['LEX']):
+        print "\nERROR: Cannot find flex."
+        print "  On Ubuntu: sudo apt-get install flex"
+        print "  On Fedora/RedHat: yum install flex"
+        sys.exit(1);
+    print "OK:  flex appears functional."
+
+    if not (env.has_key('YACC') and env['YACC']):
+        print "\nERROR: Cannot find bison."
+        print "  On Ubuntu: sudo apt-get install bison"
+        print "  On Fedora/RedHat: yum install bison"
+        sys.exit(1);
+    print "OK:  bison appears functional."
+
     # Mingw/windows stuff
     has_iphlpapi_h = conf.CheckHeader(['winsock2.h', 'iphlpapi.h'])
     has_routprot_h = conf.CheckHeader('routprot.h')
-- 
1.7.5.4



More information about the Xorp-hackers mailing list