and .dsp file updates git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4825 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			204 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
| \section{wxExpr overview}\label{exproverview}
 | |
| 
 | |
| wxExpr is a C++ class reading and writing a subset of Prolog-like syntax,
 | |
| supporting objects attribute/value pairs.
 | |
| 
 | |
| wxExpr can be used to develop programs with readable and
 | |
| robust data files. Within wxWindows itself, it is used to parse
 | |
| the {\tt .wxr} dialog resource files.
 | |
| 
 | |
| {\bf History of wxExpr}
 | |
| 
 | |
| During the development of the tool Hardy within the AIAI, a need arose
 | |
| for a data file format for C++ that was easy for both humans and
 | |
| programs to read, was robust in the face of fast-moving software
 | |
| development, and that provided some compatibility with AI languages
 | |
| such as Prolog and LISP.
 | |
| 
 | |
| The result was the wxExpr library (formerly called PrologIO), which is able to read and write a
 | |
| Prolog-like attribute-value syntax, and is additionally capable of
 | |
| writing LISP syntax for no extra programming effort.  The advantages of
 | |
| such a library are as follows:
 | |
| 
 | |
| \begin{enumerate}\itemsep=0pt
 | |
| \item The data files are readable by humans;
 | |
| \item I/O routines are easier to write and debug compared with using binary files;
 | |
| \item the files are robust: unrecognised data will just be ignored by the application
 | |
| \item Inbuilt hashing gives a random access capability, useful for when linking
 | |
| up C++ objects as data is read in;
 | |
| \item Prolog and LISP programs can load the files using a single command.
 | |
| \end{enumerate}
 | |
| 
 | |
| The library was extended to use the ability to read and write
 | |
| Prolog-like structures for remote procedure call (RPC) communication.
 | |
| The next two sections outline the two main ways the library can be used.
 | |
| 
 | |
| \subsection{wxExpr for data file manipulation}\itemsep=0pt
 | |
| 
 | |
| The fact that the output is in Prolog syntax is irrelevant for most
 | |
| programmers, who just need a reasonable I/O facility.  Typical output
 | |
| looks like this:
 | |
| 
 | |
| \begin{verbatim}
 | |
| diagram_definition(type = "Spirit Belief Network").
 | |
| 
 | |
| node_definition(type = "Model",
 | |
|   image_type = "Diamond",
 | |
|   attribute_for_label = "name",
 | |
|   attribute_for_status_line = "label",
 | |
|   colour = "CYAN",
 | |
|   default_width = 120,
 | |
|   default_height = 80,
 | |
|   text_size = 10,
 | |
|   can_resize = 1,
 | |
|   has_hypertext_item = 1,
 | |
|   attributes = ["name", "combining_function", "level_of_belief"]).
 | |
| 
 | |
| arc_definition(type = "Potentially Confirming",
 | |
|   image_type = "Spline",
 | |
|   arrow_type = "End",
 | |
|   line_style = "Solid",
 | |
|   width = 1,
 | |
|   segmentable = 0,
 | |
|   attribute_for_label = "label",
 | |
|   attribute_for_status_line = "label",
 | |
|   colour = "BLACK",
 | |
|   text_size = 10,
 | |
|   has_hypertext_item = 1,
 | |
|   can_connect_to = ["Evidence", "Cluster", "Model", "Evidence", "Evidence", "Cluster"],
 | |
|   can_connect_from = ["Data", "Evidence", "Cluster", "Evidence", "Data", "Cluster"]).
 | |
| \end{verbatim}
 | |
| 
 | |
| This is substantially easier to read and debug than a series of numbers and
 | |
| strings.
 | |
| 
 | |
| Note the object-oriented style: a file comprises a series of {\it clauses}.
 | |
| Each clause is an object with a {\it functor}\/ or object name, followed
 | |
| by a list of attribute-value pairs enclosed in parentheses, and finished
 | |
| with a full stop.  Each attribute value may be a string, a word (no quotes),
 | |
| an integer, a real number, or a list with potentially recursive elements.
 | |
| 
 | |
| The way that the facility is used by an application to read in a file is
 | |
| as follows:
 | |
| 
 | |
| \begin{enumerate}\itemsep=0pt
 | |
| \item The application creates a wxExprDatabase instance.
 | |
| \item The application tells the database to read in the entire file.
 | |
| \item The application searches the database for objects it requires,
 | |
| decomposing the objects using the wxExpr API. The database may be hashed,
 | |
| allowing rapid linking-up of application data.
 | |
| \item The application deletes or clears the wxExprDatabase.
 | |
| \end{enumerate}
 | |
| 
 | |
| Writing a file is just as easy:
 | |
| 
 | |
| \begin{enumerate}\itemsep=0pt
 | |
| \item The application creates a wxExprDatabase instance.
 | |
| \item The application adds objects to the database using the API.
 | |
| \item The application tells the database to write out the entire database,
 | |
| in Prolog or LISP notation.
 | |
| \item The application deletes or clears the wxExprDatabase.
 | |
| \end{enumerate}
 | |
| 
 | |
| To use the library, include "wxexpr.h".
 | |
| 
 | |
| \subsection{wxExpr compilation}
 | |
| 
 | |
| For UNIX compilation, ensure that YACC and LEX or FLEX are on your system. Check that
 | |
| the makefile uses the correct programs: a common error is to compile
 | |
| y\_tab.c with a C++ compiler. Edit the CCLEX variable in make.env
 | |
| to specify a C compiler. Also, do not attempt to compile lex\_yy.c
 | |
| since it is included by y\_tab.c.
 | |
| 
 | |
| For DOS compilation, the simplest thing is to copy dosyacc.c to y\_tab.c, and doslex.c to
 | |
| lex\_yy.c. It is y\_tab.c that must be compiled (lex\_yy.c is included by
 | |
| y\_tab.c) so if adding source files to a project file, ONLY add y\_tab.c
 | |
| plus the .cc files. If you wish to alter the parser, you will need YACC
 | |
| and FLEX on DOS.
 | |
| 
 | |
| The DOS tools are available at the AIAI ftp site, in the tools directory. Note that
 | |
| for FLEX installation, you need to copy flex.skl into the directory
 | |
| c:/lib.
 | |
| 
 | |
| If you are using Borland C++ and wish to regenerate lex\_yy.c and y\_tab.c
 | |
| you need to generate lex\_yy.c with FLEX and then comment out the `malloc' and `free'
 | |
| prototypes in lex\_yy.c. It will compile with lots of warnings. If you
 | |
| get an undefined \_PROIO\_YYWRAP symbol when you link, you need to remove
 | |
| USE\_DEFINE from the makefile and recompile. This is because the parser.y
 | |
| file has a choice of defining this symbol as a function or as a define,
 | |
| depending on what the version of FLEX expects. See the bottom of
 | |
| parser.y, and if necessary edit it to make it compile in the opposite
 | |
| way to the current compilation.
 | |
| 
 | |
| %To test out wxExpr compile the test program (samples/wxexpr/wxexpr.exe),
 | |
| %and try loading test.exp into the test
 | |
| %program. Then save it to another file. If the second is identical to the
 | |
| %first, wxExpr is in a working state.
 | |
| 
 | |
| \subsection{Bugs}
 | |
| 
 | |
| These are the known bugs:
 | |
| 
 | |
| \begin{enumerate}\itemsep=0pt
 | |
| \item Functors are permissable only in the main clause (object).
 | |
| Therefore nesting of structures must be done using lists, not predicates
 | |
| as in Prolog.
 | |
| \item There is a limit to the size of strings read in (about 5000 bytes).
 | |
| \end{enumerate}
 | |
| 
 | |
| \subsection{Using wxExpr}
 | |
| 
 | |
| This section is a brief introduction to using the wxExpr package.
 | |
| 
 | |
| First, some terminology.  A {\it wxExprDatabase}\/ is a list of {\it clauses},
 | |
| each of which represents an object or record which needs to be saved to a file.
 | |
| A clause has a {\it functor}\/ (name), and a list of attributes, each of which
 | |
| has a value.  Attributes may take the following types of value: string, word,
 | |
| integer, floating point number, and list.  A list can itself contain any
 | |
| type, allowing for nested data structures.
 | |
| 
 | |
| Consider the following code.
 | |
| 
 | |
| \begin{verbatim}
 | |
| wxExprDatabase db;
 | |
| 
 | |
| wxExpr *my_clause = new wxExpr("object");
 | |
| my_clause->AddAttributeValue("id", (long)1);
 | |
| my_clause->AddAttributeValueString("name", "Julian Smart");
 | |
| db.Append(my_clause);
 | |
| 
 | |
| ofstream file("my_file");
 | |
| db.Write(file);
 | |
| \end{verbatim}
 | |
| 
 | |
| This creates a database, constructs a clause, adds it to the database,
 | |
| and writes the whole database to a file.  The file it produces looks like
 | |
| this:
 | |
| 
 | |
| \begin{verbatim}
 | |
| object(id = 1,
 | |
|   name = "Julian Smart").
 | |
| \end{verbatim}
 | |
| 
 | |
| To read the database back in, the following will work:
 | |
| 
 | |
| \begin{verbatim}
 | |
| wxExprDatabase db;
 | |
| db.Read("my_file");
 | |
| 
 | |
| db.BeginFind();
 | |
| 
 | |
| wxExpr *my_clause = db.FindClauseByFunctor("object");
 | |
| int id = 0;
 | |
| wxString name = "None found";
 | |
| 
 | |
| my_clause->GetAttributeValue("id", id);
 | |
| my_clause->GetAttributeValue("name", name);
 | |
| 
 | |
| cout << "Id is " << id << ", name is " << name << "\n";
 | |
| \end{verbatim}
 | |
| 
 | |
| Note the setting of defaults before attempting to retrieve attribute values,
 | |
| since they may not be found.
 | |
| 
 |