Knowledge Representation System Generator User Guide Dave Kuhlman Reify dkuhlman@netcom.com 1-415-368-8450 Summary of How to Use KR-SG A developer uses KR-SG to produce an application by performing the following steps. Some of these steps will be unnecessary for some applications and uses: -- Installation -- Unzip the distribution file to produce the KR directory structure on the developer's hard disk. -- Describe the objects/types. -- Create a control file. -- Run MSG (the system generator) to produce source code. -- Review and make any desired changes to the generated code. -- Compile the generated code to produce a library. -- Compile supporting code (DB, SUP). -- Compile KRC (the Knowledge Representation Compiler). -- Make changes to the sample application. -- Compile the sample application. -- Modify the generator to customize generated code. -- Integrate the generated REXX interface support. -- Integrate with VX-REXX. -- Integrate generated template insertion code into you text editor (EPM or Preditor/2). Installation Unzip the distribution file to produce the KR directory structure on the developer's hard disk -- Doing so will produce the following directory tree: KR-SG -- User Guide Page 1 kr ----+---- h (some header and include files | +---- sup (support code for KrStrings, KrStreams, etc) | +---- db (database support code, BTree glue functions, etc) | +---- gen (code and support for the generator itself) | +---- kr (the generated code goes here) | +---- krc (the KR command line compiler/decompiler) | +---- test (a sample program) | +---- libx (x: b=Borland, i=IBM Cset++, w=WATCOM) Describe the objects/types Produce a knowledge representation type specification file (called, say, myapp.msg). This file contains a description of each type that you intend to define and manipulate. For each type, you specify the fields in that type. Each field must be one of the following types: (1) integer, (2) float, (3) string (a pointer to a KrString), (4) boolean, (5) user defined type (a pointer to a user defined type), (6) a list of one of the above. In addition, optionally specify a superclass for the type. Here is the grammar for the contents of the KR specification file. Curly brackets indicate constructions that can be repeated zero or more times. Vertical bars indicate alternatives. kr_spec_file ::= { kr_spec_element } ; kr_spec_element ::= kr_directive | kr_rule ; kr_rule ::= "(" "structure" type_name { spec } ")" ; spec ::= super | contents ; super ::= "(" "superclass" type_name ")" ; contents ::= "(" "contents" { field } ")" ; field ::= "(" field_name type ")" ; Comments -- Lines with '#' as the first non-blank character are treated as comments. The directory /kr/gen contains a sample specification file: kr.msg. Here are some rules to remember while creating the definitions of your types: -- Do not define two fields with the same name, even within two KR-SG -- User Guide Page 2 different types. You will be able to do this someday; I'll fix it eventually; until then ... -- Do not define two types of fields whose names differ only by case. -- Do not define any field whose name ends in an underscore. KR-SG creates some fields that do, and you don't want conflicts. -- When you define a field as a non-primitive type, i.e. a field whose type is one which you define yourself, you must define it as a pointer. -- When you define a field as a list of anything, you must also define it as a list of pointers. The lists generated by KR-SG are type-safe, but only hold pointers to objects. -- You can define fields that are lists of strings and fields that are lists of of one of your defined types. But you can't define a field that is a list of intergers, a list of booleans, or a list of floats. (This will be considered for a future enhancement.) The MSG Control File Create a control file (Optional) -- This file contains command line flags used by the generator. These flags specify, for example, whether to generate specific types of code (C++ code, parser code, etc), the input specification file, whether to generate comments in the code, the output file base name, etc. This file is optional, though it makes things easier. you can enter flags on the control line if you wish. If you enter flags on the control line, they override the same flags in the control file. MSG accepts the following flags: -a generate all files (= -h + -m + -p) -h generate header file (.HPP file) -m generate method code (.CPP file) -p generate compiler code (.G and .SOR files) -C generate comments in code -iaaa input specification file is aaa.msg -obbb output base file name is bbb. Recommended: 7 characters or less. Output files will be bbb.hpp, bbb.cpp, bbb.h bbbg.g bbbg.h, and bbbs.sor. The /kr/gen directory contains a sample control file kr.cfg. This control file uses the input specification file kr.msg and writes generated code to files kr*.*. KR-SG -- User Guide Page 3 Run MSG Run MSG, the system generator, to generate source code -- MSG reads the type specification file and generates the various code output files. If you included flags in the control file (MSG.CFG) to specify the input specification file and the base name of the output files, then the following command will run MSG: msg @kr.cfg Path -- The directory /krsg/bin must be on your path. See command files setenv*.cmd in the /krsg directory. A word about the Icon executables for OS/2 There are two executable files for the Icon programming language: icont.exe and iconx.exe. iconx.exe is needed when you run msg.exe or any other Icon program. You will need icont.exe only if you change the source code files. icont.exe is the translator; it was used to produce the file msg.exe. There are several batch files that can be used to rebuild msg.exe: -- cmpl.cmd -- compile a single source code file (*.icn), no link. -- cmpllink.cmd -- compile a single source code file, then link it with the other previously compiled files (*.u1 and *.u2). User this when you have modified a single Icon source file. -- build.cmd -- compile all required source files, then link. Use this the first time in order to produce all compiled files. The file iconx.exe is needed when you run the executable produced by icont.exe; it contains the interpreter for Icon. The "executable" produced by icont.exe contains a stub that refers to iconx.exe. You must have iconx.exe somewhere on your path. Contact the Icon Project to obtain executables for other platforms or for other support for the Icon Programming lanaguage: The Icon Project Department of Computer Science Gould-Simpson Building University of Arizona Tucson, Arizona 85721 1-602-621-8448 Internet: icon-project@cs.arizona.edu Copy the Generated Files KR-SG -- User Guide Page 4 Copy the generated files to the /kr/kr directory. A batch file in the /kr/kr directory (COPYGEN.CMD) can be used to do this copy. Review and make any desired changes to the generated code This may not be necessary. You should attempt to avoid modifying the generated code, or at least to delay doing so as long as possible. If you make changes to the generated files, there is no way for you to change the type specification file and re-generate these file while automatically keeping your changes. Still let's look at where some of the different types of code go. MSG generates the following files: myapp.hpp -- C++ header file for the type definitions. Contains a C++ class definition for each type defined in the type specification file. Also contains a record (struct) definition for each for type used in saving and loading each type into the database. Also contains a list class for each type. myapp.cpp -- C++ code for the member functions for each class/type. For each type, the following functions are generated: (1) default constructor, (2) copy constructor, (3) virtual destructor, assignment operator, (5), Load function to load object from a database, (6) Save function to save function into database, (7) Decompile function to translate the object into a text form, (8) GenIpf function that produces code for the IPFC help compiler. Also contains member function definitions for the member functions in the list classes. myappg.g -- Parser grammar used to produce a compiler for the types specified. This file contains a grammar rule for each type that you define and it contains a rule for each field in that type. This code parses (decompiled) input and produces a parse tree. myapps.sor -- Tree parser grammar used to produce a compiler for the types specified. The grammar file (myappg.g) is use to parse the input and produce a parse tree; the tree parser grammar file is used to walk that parse tree and build the objects described in it. This file contains a tree grammar rule for each type that you define and for each field in that type. In each rule there are actions used to build the objects. If you want to modify the way the objects are built or to add code that performs additional actions, filters objects, modifies objects, reports on the objects being built, then this is a good place to look. myapp*.h -- miscellaneous header files. Compile the Code Compile the generated code to produce a library. The /kr/kr KR-SG -- User Guide Page 5 directory contains make files (KRx.MAK, where x = 'b' for Borland for OS/2, 'w' for WATCOM for OS/2, and 'i' for IBM CSet++) for compiling the files generated by the sample control file and specification files (MSG.CFG and KR.MSG). Path -- The directory /krsg/bin must be on your path. See command files setenv*.cmd in the /krsg directory. In order to compile this code, you will need to translate the grammar files to C/C++ source code. In order to do this (the make file supports it), you will need to have header files executable files for PCCTS (antler.exe and dlg.exe). The header files are provided in this package in directory /krsg/pccts. Executables for OS/2 are provided with this package (KR-SG). PCCTS is in the public domain and is distributed in source code form. It is available from Internet anonymous ftp site: everest.ee.umn.edu:/pub/pccts /pub/pccts/sorcerer Compile the Code in the Support Directories Compile supporting code in the following directories: /kr/db, /kr/sup. These contain make files (DBx.MAK and SUPx.MAK). You will need either (1) to acquire the Softfocus BTree library or (2) to change the glue functions in btree.cpp so that they use some other file access support code. The Softfocus BTree library is distributed in source code form. You can contact Softfocus at: Softfocus 1343 Stanbury Rd. Oakville, Ontario, Canada L6L 2J5 1-905-825-0903 Modify and then compile KRC In IRC (the Knowledge Representation Compiler) there are a few variable declarations in krc.cpp whose data types you will have to change to match the type of the top level object that you have defined. The /kr/krc directory contains make files (KRCx.MAK). This produces a command line compiler which can be used to: -- Create a database (command line flag -c). -- Compile a text file into a database (-a). -- Decompile a file from a database into a text file (-x). -- Delete an object from a database (-d). KR-SG -- User Guide Page 6 Run krc.exe with no arguments to get quick help. Modify and Compile the Sample Application The sample application is in directory /kr/test. Make changes to the sample application. The calls to the Set_xxx() functions will have to be changed. Compile the sample application. Run it. It should produce a database, a decompiled file, and a .IPF file (that can be compiled with IPFC.EXE. Modifying the Code Generator (Optional) Modify the generator to customize generated code. This step is optional. Do this if, for example, you need to embed hooks or function calls into the generated code. You will need to know how to write code in the Icon programming language in order to do this. You can help yourself here by going to the /kr/gen directory, uncommenting the line at the beginning of GEN.ICN that defines msg_debug, then run MSG.EXE using the '-C' flag for comments (either in the MSG.CFG file or on the command line). This will generate comments in your .CPP file containing the file and line numbers of the code that produced the generated code. This will help you find the location where you need to make changes. Hopefully, you will be able to add a line of code that calls your function to a list of strings (lines) that become the generated code. REXX Support [This is work in progress. Under construction.] Integrate the generated REXX interface support. The sample application (/test/test.cpp) contains a sample REXX interface. In addition, you will need to provide the C code which implements procedures that you want your users to be able to call from REXX code. KR-SG helps you with this; it generates code that provides data access procedures that can be called from REXX to get and set the contents of member data items in your defined data types. This code is in the file krrex.inc. You will need to #include this into your (sample/test/real) application. VX-REXX Support [I haven't figured this one out yet, but I'm working on it.] KR-SG -- User Guide Page 7 Text Editor Support [I am thinking about generating template insertion code for one or more text editors, possibly EPM and/or Preditor/2 from Compuware. Is this worth the effort? Or is cut and paste good enough. Until I implement this, you can ignore it.] Create Your Own Application Go to directory /kr/gen. Create a new file myapp.cfg. Create a new file myapp.msg Run the code generator: msg @myapp.cfg Create a new directory: /kr/myapp. Pick your own name, but make it seven letters or less. Copy the following files to directory /kr/myapp: copy ../kr/copygen.cmd copy ../kr/ast.c copy ../kr/kr.mak myapp.mak Note: I had to make a change to the file ast.c in order to satisfy the Borland compiler, so put this "corrected" copy of ast.c in your application directory. Edit the files copygen.cmd and myapp.mak. Change all occurances of 'kr' to 'myapp'. Run copygen.cmd. Compile the code. For Borland for OS/2 use the following: make /f myapp.mak KR-SG -- User Guide Page 8