/code/Parser.java
Java | 1484 lines | 1190 code | 71 blank | 223 comment | 336 complexity | a14be171636dfe0a638ad31664634ce2 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- import java.io.*;
- import java.util.*;
- /** This Parser is an adaptation of the Mock-a-Java parser built for Nobo
- Komogata's Compiler class (CIS 341) in Spring 2000 at Penn. It is NOT an elegant
- or professional-quality parser -- just a utility to allow Domain Theories written in
- Horn Clauses to be read into Kinship programs and converted to the proper Java objects
- for reasoning there. The Context-Free Grammar defining a Domain Theory is documented
- in {@link DomainTheoryGrammar}.
- //
- When constructed with a {@link Tokenizer}, a Parser will construct a Kinship domain theory
- from the tokens found in the <code>Tokenizer's</code> input file.
- @author Gary Morris, Northern Virginia Community College garymorris2245@verizon.net
- */
- public class Parser {
- public static String errorFound = "";
- public static ArrayList<Object> cachedStdMacros;
- TokenScanned current;
- Linus lineMan, macroLineMan;
- Tokenizer scanner, macroScanner;
- String filePath;
- DomainTheory dTheory;
- /** Construct a Parser from a DomainTheory file.
- @param tok a <code>Tokenizer</code> which parses tokens from an input file on demand.
- */
- public Parser(Tokenizer tok) {
- scanner = tok;
- lineMan = scanner.lineServer;
- this.filePath = tok.filePath;
- }
- /** Construct a Parserfrom a DomainTheory file and a Standard_Macros file.
- @param dtTokens a <code>Tokenizer</code> which parses tokens from a DomainTheory file on demand.
- @param macroTokens a <code>Tokenizer</code> which parses tokens from a Macro file on demand.
- */
- public Parser(Tokenizer dtTokens, Tokenizer macroTokens) {
- scanner = dtTokens;
- lineMan = scanner.lineServer;
- this.filePath = dtTokens.filePath;
- macroScanner = macroTokens;
- macroLineMan = macroScanner.lineServer;
- }
- /** Return the category of the predicate <code>symbol</code>.
- @param symbol a String which has been identified as a predicate symbol in a Horn Clause.
- @return either {@link PrimitiveCategory} (a built-in predicate the Kinship system understands)
- or {@link CulturalCategory} (a kinship term in the language of the target culture).
- */
- public static PredCategory determinePrimitive(String symbol, DomainTheory dt) {
- // Identify the 19 Primitive Predicates as special
- // Also consider userDefinedProperties and Math predicates as primitive predicates
- if ((symbol.equals("father")) || (symbol.equals("mother")) || (symbol.equals("son"))
- || (symbol.equals("daughter")) || (symbol.equals("husband")) || (symbol.equals("wife"))
- || (symbol.equals("male")) || (symbol.equals("female")) || (symbol.equals("elder"))
- || (symbol.equals("younger")) || (symbol.equals("dead")) || (symbol.equals("divorced"))
- || (symbol.equals("not")) || (symbol.equals("equal")) || (symbol.equals("parent"))
- || (symbol.equals("child")) || (symbol.equals("spouse"))
- || (symbol.equals("allowCreation")) || (symbol.equals("gender"))
- || (dt != null && dt.userDefinedProperties != null
- && dt.userDefinedProperties.containsKey(symbol))) {
- return new PrimitiveCategory();
- } // Treat the Math predicates as a special kind of Primitive
- else if ((symbol.equals("lessThan")) || (symbol.equals("greaterThan"))
- || (symbol.equals("lessOrEql")) || (symbol.equals("greaterOrEql"))
- || (symbol.equals("contains"))) {
- return new MathCategory();
- } else {
- return new CulturalCategory();
- }
- } // end of method determinePrimitive
- /** Assemble information about a parsing error encountered, then throw a {@link KSParsingErrorException}.
- @param msgOut a String describing the exact error found.
- @throws a <code>KSParsingErrorException</code>.
- */
- public void error(String msgOut) throws KSParsingErrorException {
- msgOut += "\nCurrent = " + current.token + ": " + current.lexeme;
- msgOut += "\nOn Line # " + current.lineNum + " Character Position: " + current.charPos
- + " of " + filePath;
- if (Parser.errorFound.length() < 10) {
- msgOut += "\n" + lineMan.lineImage;
- }
- throw new KSParsingErrorException(msgOut);
- } // end of error method
- /** Begin the parse of a Domain Theory.
- //
- DomainTheory -> LanguageName, HeaderOpts, StandardMacros, Theory.
- @throws <code>KSParsingErrorException</code>
- */
- public DomainTheory parseDomainTheory() throws KSParsingErrorException, KSConstraintInconsistency {
- String languageName = parseLanguageName();
- try {
- dTheory = new DomainTheory(languageName);
- } catch (ExceptionInInitializerError e) {
- System.out.println("Cause is " + e.getCause());
- }
- dTheory.filePath = filePath;
- parseHeaderOpts();
- if (dTheory.addressTerms) {
- int start = languageName.length() - 5;
- if (!languageName.substring(start).equals("(Adr)")) {
- throw new KSParsingErrorException("Language Name '" + languageName
- + "' violates convention for Terms of Address.\n"
- + "Should be <langName>(Adr)");
- }
- } // end of validity check on languageName
- parseStandardMacros();
- if (current.token.equals("$")) {
- return dTheory; // There were no definitions
- }
- parseTheory();
- dTheory.validateSynonymsAndUmbrellas();
- return dTheory;
- } // end of method parseDomainTheory
- /* LanguageName -> leftParen, "languageName", comma, string, rightParen.
- First: [leftParen] Follow: [leftParen, symbol]
- */
- private String parseLanguageName() throws KSParsingErrorException {
- String name;
- current = scanner.lookAhead();
- if (current.token.equals("leftParen")) {
- scanner.readToken(); // consume the leftParen
- current = scanner.readToken(); // read next, which must be the string "languageName"
- if (!current.lexeme.equals("languageName")) {
- error("parseLanguageName seeking the string 'languageName'. ");
- }
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseLanguageName seeking a comma. ");
- }
- current = scanner.readToken(); // read next, which must be a string
- if (!current.token.equals("string")) {
- error("parseLanguageName seeking a string. ");
- }
- name = current.lexeme;
- int where = name.indexOf("(Adr)"); // where = end of langName without '(Adr)'
- if (where == -1) {
- where = name.length();
- }
- if (name.substring(0, where).indexOf("(") > 0 || name.substring(0, where).indexOf(")") > 0) {
- error("The language name '" + name + "' contains a parenthesis -- Prohibited Character.\n"
- + "Replace with angle-bracket or square-bracket.");
- }
- current = scanner.readToken(); // read next, which must be a rightParen.
- if (!current.token.equals("rightParen")) {
- error("parseLanguageName seeking a rightParen. ");
- }
- return name;
- } // end of if = leftParen
- else {
- error("First non-comment line of file MUST contain '(languageName, name)'.");
- }
- return "ERROR";
- } // end of method parseLanguageName()
- /* HeaderOpts -> leftParen, HdrOpts2, HeaderOpts.
- | \empty.
- First: [leftParen] Follow: [symbol]
- */
- private void parseHeaderOpts() throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.token.equals("leftParen")) {
- scanner.readToken(); // consume the leftParen
- parseHdrOpts2();
- parseHeaderOpts();
- return;
- } // end of if = leftParen
- if (current.token.equals("symbol")) {
- return;
- }
- if (current.token.equals("$")) {
- return;
- }
- error("parseHeaderOpts seeking leftParen or symbol.");
- return;
- } // end of method parseHeaderOpts
- /*
- HdrOpts2 -> "author", comma, string, rightParen.
- | "date", comma, string, rightParen.
- | "partial", comma, Boolean, rightParen.
- | "address", comma, Boolean, rightParen.
- | "polygamyOK", comma, Boolean, rightParen.
- | "citation", comma, string, rightParen.
- | "non_term", comma, FlagOrKinTerm, OtherFlagOrKinTerm, rightParen.
- | "recursiveLevels", comma, integer, rightParen.
- | "userDefinedProperties", UDProps, rightParen.
- | "synonyms", comma, TermPairs, rightParen.
- | "umbrellas", comma, TermListPairs, rightParen.
- | "overlaps", comma, TermListPairs, rightParen.
- First: ["author", "date", "partial", "polygamyOK", "citation", "non_term",
- "recursiveLevels", "userDefinedProperties", "umbrellas", "synonyms", "overlaps"]
- Follow: [leftParen, symbol]
- */
- private void parseHdrOpts2() throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.lexeme.equals("author")) {
- scanner.readToken(); // consume the string 'author'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- current = scanner.readToken(); // read next, which must be a string
- if (!current.token.equals("string")) {
- error("parseHdrOpts2 seeking a string.");
- } else {
- dTheory.author = current.lexeme;
- }
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = author
- if (current.lexeme.equals("date")) {
- scanner.readToken(); // consume the string 'date'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- current = scanner.readToken(); // read next, which must be a string
- if (!current.token.equals("string")) {
- error("parseHdrOpts2 seeking a string.");
- } else {
- Date cDate = null;
- try {
- cDate = UDate.parse(current.lexeme);
- }catch(KSDateParseException dpe) {
- error("While parsing createion date: " + dpe);
- }
- dTheory.createDate = UDate.formatAsXSD(cDate);
- }
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = date
- if (current.lexeme.equals("partial")) {
- scanner.readToken(); // consume the string 'partial'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- dTheory.partial = parseBoolean();
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = partial
- if (current.lexeme.equals("address")) {
- scanner.readToken(); // consume the string 'address'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- dTheory.addressTerms = parseBoolean();
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = partial
- if (current.lexeme.equals("polygamyOK")) {
- scanner.readToken(); // consume the string 'polygamyOK'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- dTheory.polygamyOK = parseBoolean();
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = polygamyOK
- if (current.lexeme.equals("citation")) {
- scanner.readToken(); // consume the string 'citation'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- current = scanner.readToken(); // read next, which must be a string
- if (!current.token.equals("string")) {
- error("parseHdrOpts2 seeking a string.");
- } else {
- dTheory.citation = current.lexeme;
- }
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = citation
- if (current.lexeme.equals("non_term")) {
- scanner.readToken(); // consume the string 'non_term'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- parseFlagOrKinTerm();
- parseOtherFlagOrKinTerm();
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = non_term
- if (current.lexeme.equals("recursiveLevels")) {
- scanner.readToken(); // consume the string 'recursiveLevels'
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- current = scanner.readToken(); // read next, which must be an integer
- if (!current.token.equals("integer")) {
- error("parseHdrOpts2 seeking an integer.");
- }
- dTheory.levelsOfRecursion = current.intVal;
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = recursiveLevels
- if (current.lexeme.equals("userDefinedProperties")) {
- scanner.readToken(); // consume the string 'userDefinedProperties'
- dTheory.userDefinedProperties = new TreeMap();
- parseUDProps();
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = userDefinedProperties
- if (current.lexeme.equals("synonyms")) {
- scanner.readToken(); // consume the string 'synonyms'
- if (dTheory.synonyms != null) {
- error("Duplicate synonym declarations.");
- }
- dTheory.synonyms = new TreeMap();
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- parseTermPairs(dTheory.synonyms, false);
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = synonyms
- if (current.lexeme.equals("umbrellas")) {
- scanner.readToken(); // consume the string 'umbrellas'
- if (dTheory.umbrellas != null) {
- error("Duplicate umbrella declarations.");
- }
- dTheory.umbrellas = new TreeMap();
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- parseTermListPairs(dTheory.umbrellas, false);
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = userDefinedProperties
- if (current.lexeme.equals("overlaps")) {
- scanner.readToken(); // consume the string 'overlaps'
- if (dTheory.overlaps != null) {
- error("Duplicate overlapping term declarations.");
- }
- dTheory.overlaps = new TreeMap();
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseHdrOpts2 seeking a comma.");
- }
- parseTermListPairs(dTheory.overlaps, true);
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseHdrOpts2 seeking a rightParen.");
- }
- return;
- } // end of if = synonyms
- error("parseHdrOpts2 seeking 'author' 'date' 'polygamyOK' 'citation' 'non_term' 'recursiveLevels' "
- + "'userDefinedProperties' 'synonyms' 'umbrellas' 'overlaps' or 'partial'.");
- } // end of method parseHdrOpts
- /* Boolean -> "true".
- | "false".
- First: ["true", "false"] Follow: [comma, rightParen]
- */
- private boolean parseBoolean() throws KSParsingErrorException {
- current = scanner.readToken(); // consume next, which must be a symbol = "true" or "false"
- if (!current.token.equals("symbol")) {
- error("parseBoolean seeking symbol ('true' or 'false').");
- }
- if (current.lexeme.equals("true")) {
- return true;
- }
- if (current.lexeme.equals("false")) {
- return false;
- }
- error("parseBoolean seeking symbol ('true' or 'false').");
- return false;
- } // end of method parseBoolean
- /*U_D_Props -> comma, leftParen, starName, comma, "type", comma, Type, comma, "single_value", comma, Boolean, UDP_Opts, rightParen, U_D_Props.
- | \empty.
- First: [comma] Follow: [rightParen]
- */
- private void parseUDProps() throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.token.equals("comma")) {
- scanner.readToken(); // consume the comma
- current = scanner.readToken(); // read next, which must be a leftParen
- if (!current.token.equals("leftParen")) {
- error("parseUDProps seeking a leftParen.");
- }
- current = scanner.readToken(); // read next, which must be a starName
- if (!current.token.equals("starName")) {
- error("parseUDProps seeking a starName.");
- }
- String starNam = current.lexeme; // this will be the particular *-name user has chosen
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseUDProps seeking a comma.");
- }
- UserDefinedProperty newProp = new UserDefinedProperty(starNam);
- dTheory.userDefinedProperties.put(starNam, newProp);
- current = scanner.readToken(); // read next, which must be the word "type"
- if ((!current.token.equals("symbol")) || (current.lexeme == null) || (!current.lexeme.equals("type"))) {
- error("parseUDProps seeking keyword 'type'.");
- }
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseUDProps seeking a comma.");
- }
- parseType(newProp);
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseUDProps seeking a comma.");
- }
- current = scanner.readToken(); // read next, which must be the word "single_value"
- if ((!current.token.equals("symbol")) || (current.lexeme == null) || (!current.lexeme.equals("single_value"))) {
- error("parseUDProps seeking keyword 'single_value'.");
- }
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseUDProps seeking a comma.");
- }
- newProp.singleValue = parseBoolean();
- parseUDP_Opts(newProp);
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseUDProps seeking a rightParen.");
- }
- // VALIDITY CHECKS
- if ((!newProp.singleValue) && (newProp.typ.equals("boolean"))) {
- error("UserDefinedProperty '" + starNam + "' is boolean with multiple values. Not allowed.");
- }
- if ((newProp.minVal != null) && (newProp.maxVal != null)
- && (newProp.maxVal.intValue() < newProp.minVal.intValue())) {
- error("UserDefinedProperty '" + starNam + "' has max value less than its min value. Does not compute!");
- }
- if ((newProp.defaultValue != null) && (newProp.minVal != null)
- && (((Number) newProp.minVal).intValue() > ((Number) newProp.defaultValue).intValue())) {
- error("UserDefinedProperty '" + starNam + "' has default value less than its min value. Does not compute!");
- }
- if ((newProp.defaultValue != null) && (newProp.maxVal != null)
- && (((Number) newProp.maxVal).intValue() < ((Number) newProp.defaultValue).intValue())) {
- error("UserDefinedProperty '" + starNam + "' has default value greater than its max value. Does not compute!");
- }
- if ((newProp.validEntries != null) && (newProp.validEntries.size() > 0) && (newProp.maxVal != null)) {
- for (int i = 0; i < newProp.validEntries.size(); i++) {
- if (((Number) newProp.maxVal).intValue() < ((Number) newProp.validEntries.get(i)).intValue()) {
- error("UserDefinedProperty '" + starNam + "' has a 'permissible value' greater than its max value. Does not compute!");
- }
- }
- }
- if ((newProp.validEntries != null) && (newProp.validEntries.size() > 0) && (newProp.minVal != null)) {
- for (int i = 0; i < newProp.validEntries.size(); i++) {
- if (((Number) newProp.minVal).intValue() > ((Number) newProp.validEntries.get(i)).intValue()) {
- error("UserDefinedProperty '" + starNam + "' has a 'permissible value' less than its minimum value. Does not compute!");
- }
- }
- }
- parseUDProps();
- return;
- } // end of if = comma
- if (current.token.equals("rightParen")) {
- return; // we hit the end
- }
- error("parseUDProps seeking comma or rightParen.");
- return;
- } // end of method parseUDProps
- /* Type -> "integer".
- | "float".
- | "string".
- | "boolean".
- | "individual".
- | "Individual".
- | "person".
- | "Person".
- First: [<all-the-above>] Follow: [comma]
- */
- private void parseType(UserDefinedProperty prop) throws KSParsingErrorException {
- current = scanner.readToken(); // consume next, which must be a valid type
- if ((!(current.token.equals("symbol") || current.token.equals("var"))) || (current.lexeme == null)) {
- error("parseType seeking a valid data type.");
- }
- if ((current.lexeme.equalsIgnoreCase("integer"))) {
- prop.typ = "integer";
- } else if (current.lexeme.equals("float")) {
- prop.typ = "float";
- } else if (current.lexeme.equals("string")) {
- prop.typ = "string";
- } else if (current.lexeme.equals("boolean")) {
- prop.typ = "boolean";
- } else if ((current.lexeme.equalsIgnoreCase("individual")) || (current.lexeme.equalsIgnoreCase("person"))) {
- prop.typ = "individual";
- } else {
- error("parseType seeking a valid data type.");
- }
- return;
- } // end of method parseType
- /* UDP_Opts -> comma, RestrictOrDefault, UDP_Opts.
- | \empty.
- First: [comma] Follow: [rightParen]
- */
- private void parseUDP_Opts(UserDefinedProperty prop) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.token.equals("comma")) { // non-empty
- scanner.readToken(); // consume the comma
- parseRestrictOrDefault(prop);
- parseUDP_Opts(prop);
- } else if (current.token.equals("rightParen")) {
- return; // empty
- } else {
- error("parseUDP_Opts seeking a comma or rightParen.");
- }
- } // end of method parseUDP_Opts
- /* RestrictOrDefault -> "restricted_to", comma, leftParen, Ints_Floats_Strings, rightParen.
- | "default", comma, Int_Float_String.
- | "max", comma, Int_Float.
- | "min", comma, Int_Float.
- First: ["restricted_to", "default", "max", "min"] Follow: [comma, rightParen]
- */
- private void parseRestrictOrDefault(UserDefinedProperty udp) throws KSParsingErrorException {
- current = scanner.readToken(); // read next, which must be a keyword
- if ((!current.token.equals("symbol")) || (current.lexeme == null)) {
- error("parseRestrictOrDefault seeking keywords: 'default', 'max', min', or 'restricted_to'.");
- }
- if (current.lexeme.equals("restricted_to")) { // restricted values declaration
- if ((udp.typ.equals("boolean")) || (udp.typ.equals("individual"))) {
- error("UserDefinedProperty '" + udp.starName + "' is " + udp.typ + " but has restricted values. Not allowed.");
- }
- current = scanner.readToken(); // read next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseRestrictOrDefault seeking a comma.");
- }
- current = scanner.readToken(); // read next, which must be a leftParen
- if (!current.token.equals("leftParen")) {
- error("parseRestrictOrDefault seeking a leftParen.");
- }
- udp.validEntries = parseInts_Floats_Strings(udp);
- current = scanner.readToken(); // read next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseRestrictOrDefault seeking a rightParen.");
- }
- } else if (current.lexeme.equals("default")) { // default value declaration
- current = scanner.readToken(); // read next, which must be a comma
- if (udp.typ.equals("individual")) {
- error("UserDefinedProperty '" + udp.starName + "' is " + udp.typ + ". Default value not allowed.");
- }
- if (!current.token.equals("comma")) {
- error("parseRestrictOrDefault seeking a comma.");
- }
- udp.defaultValue = parseInt_Float_String();
- } else if (current.lexeme.equals("max")) {
- current = scanner.readToken(); // read next, which must be a comma
- if ((udp.typ.equals("string")) || (udp.typ.equals("boolean")) || (udp.typ.equals("individual"))) {
- error("UserDefinedProperty '" + udp.starName + "' is " + udp.typ + ". Max value not allowed.");
- }
- if (!current.token.equals("comma")) {
- error("parseRestrictOrDefault seeking a comma.");
- }
- udp.maxVal = parseInt_Float();
- if (!current.token.equals(udp.typ)) {
- error("UserDefinedProperty '" + udp.starName + "' has type = " + udp.typ + ", but Max Value is a " + current.token);
- }
- } else if (current.lexeme.equals("min")) {
- current = scanner.readToken(); // read next, which must be a comma
- if ((udp.typ.equals("string")) || (udp.typ.equals("boolean")) || (udp.typ.equals("individual"))) {
- error("UserDefinedProperty '" + udp.starName + "' is " + udp.typ + ". Min value not allowed.");
- }
- if (!current.token.equals("comma")) {
- error("parseRestrictOrDefault seeking a comma.");
- }
- udp.minVal = parseInt_Float();
- if (!current.token.equals(udp.typ)) {
- error("UserDefinedProperty '" + udp.starName + "' has type = " + udp.typ + ", but Max Value is a " + current.token);
- }
- } else {
- error("parseRestrictOrDefault seeking keywords: 'default', 'max', min', or 'restricted_to'.");
- }
- } // end of method parseRestrictOrDefault
- /* Int_Float -> integer.
- | float.
- First: [integer, float] Follow: [comma, rightParen]
- */
- private Number parseInt_Float() throws KSParsingErrorException {
- current = scanner.readToken(); // read next, must be int or float.
- if (current.token.equals("integer")) {
- return new Integer(current.intVal);
- }
- if (current.token.equals("float")) {
- return new Float(current.floatVal);
- }
- error("parseInt_Float seeking an integer or a float.");
- return null;
- } // end of method parseInt_Float
- /* Int_Float_String -> integer.
- | float.
- | string.
- First: [integer, float, string] Follow: [comma, rightParen]
- */
- private Object parseInt_Float_String() throws KSParsingErrorException {
- current = scanner.readToken(); // read next, must be int, float, string
- if (current.token.equals("integer")) {
- return new Integer(current.intVal);
- }
- if (current.token.equals("float")) {
- return new Float(current.floatVal);
- }
- // Accept symbols as strings -- folks will forget the quotes.
- if ((current.token.equals("string")) || (current.token.equals("symbol"))) {
- return current.lexeme;
- }
- error("parseInt_Float_String seeking an integer, float, or string.");
- return null;
- } // end of method parseInt_Float_String
- /* Ints_Floats_Strings -> Ints.
- | Floats.
- | Strings.
- First: [integer, float, string] Follow: [rightParen]
- */
- private ArrayList<Object> parseInts_Floats_Strings(UserDefinedProperty udp) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (!udp.typ.equals(current.token)) {
- error("UserDefinedProperty '" + udp.starName + "' has type = " + udp.typ + ", but 'legal values' has a " + current.token);
- }
- if (current.token.equals("integer")) {
- return parseInts();
- }
- if (current.token.equals("float")) {
- return parseFloats();
- }
- if (current.token.equals("string")) {
- return parseStrings();
- }
- error("parseInts_Floats_Strings seeking an integer, float, or string.");
- return null;
- } // end of method parseInts_Floats_Strings
- /* Ints -> integer, MoreInts.
- First: [integer] Follow: [rightParen]
- */
- private ArrayList<Object> parseInts() throws KSParsingErrorException {
- ArrayList<Object> list = new ArrayList<Object>();
- current = scanner.readToken(); // read next, which must be an integer
- if (!current.token.equals("integer")) {
- error("parseInts seeking an integer.");
- }
- list.add(new Integer(current.intVal));
- parseMoreInts(list);
- return list;
- } // end of method parseInts
- /* MoreInts -> comma, integer, MoreInts.
- | \empty
- First: [comma] Follow: [rightParen]
- */
- private void parseMoreInts(ArrayList<Object> list) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.token.equals("comma")) {
- scanner.readToken(); // consume the comma
- current = scanner.readToken(); // read next, which must be an integer
- if (!current.token.equals("integer")) {
- error("parseMoreInts seeking an integer.");
- }
- list.add(new Integer(current.intVal));
- parseMoreInts(list);
- return;
- } else if (current.token.equals("rightParen")) {
- return;
- } else {
- error("parseMoreInts seeking a comma or a rightParen.");
- }
- } // end of method parseMoreInts
- /* Floats -> float, MoreFloats.
- First: [float] Follow: [rightParen]
- */
- private ArrayList<Object> parseFloats() throws KSParsingErrorException {
- ArrayList<Object> list = new ArrayList<Object>();
- current = scanner.readToken(); // read next, which must be a float
- if (!current.token.equals("float")) {
- error("parseFloats seeking a float.");
- }
- list.add(new Float(current.floatVal));
- parseMoreFloats(list);
- return list;
- } // end of method parseFloats
- /* MoreFloats -> comma, float, MoreFloats.
- | \empty.
- First: [comma] Follow: [rightParen]
- */
- private void parseMoreFloats(ArrayList<Object> list) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.token.equals("comma")) {
- scanner.readToken(); // consume the comma
- current = scanner.readToken(); // read next, which must be a float
- if (!current.token.equals("float")) {
- error("parseMoreFloats seeking a float.");
- }
- list.add(new Float(current.floatVal));
- parseMoreFloats(list);
- return;
- } else if (current.token.equals("rightParen")) {
- return;
- } else {
- error("parseMoreFloats seeking a comma or a rightParen.");
- }
- } // end of method parseMoreFloats
- /* Strings -> string, MoreStrings.
- First: [string] Follow: [rightParen]
- */
- private ArrayList<Object> parseStrings() throws KSParsingErrorException {
- ArrayList<Object> list = new ArrayList<Object>();
- current = scanner.readToken(); // read next, which must be a string
- if (!current.token.equals("string")) {
- error("parseStrings seeking a string.");
- }
- list.add(current.lexeme);
- parseMoreStrings(list);
- return list;
- } // end of method parseStrings
- /* MoreStrings -> comma, string, MoreStrings.
- | \empty.
- First: [comma] Follow: [rightParen]
- */
- private void parseMoreStrings(ArrayList<Object> list) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if (current.token.equals("comma")) {
- scanner.readToken(); // consume the comma
- current = scanner.readToken(); // read next, which must be a string
- if (!current.token.equals("string")) {
- error("parseMoreStrings seeking a string.");
- }
- list.add(current.lexeme);
- parseMoreStrings(list);
- return;
- } else if (current.token.equals("rightParen")) {
- return;
- } else {
- error("parseMoreStrings seeking a comma or a rightParen.");
- }
- } // end of method parseMoreStrings
- public DomainTheory parseMacrosOnly() throws KSParsingErrorException {
- dTheory = new DomainTheory();
- current = scanner.lookAhead();
- KinTermDef ktd = parseKinTermDef();
- parseSignatureString(ktd);
- parseExpansion(ktd);
- for (int i = 0; i < ktd.expandedDefs.size(); i++) { // number the expanded defintions
- ((ClauseBody) ktd.expandedDefs.get(i)).seqNmbr = i;
- }
- parseOtherDefs();
- return dTheory;
- }
- // StandardMacros -> KinTermDef, SignatureString, Expansion, OtherDefs.
- // | \empty.
- private void parseStandardMacros() throws KSParsingErrorException {
- if (macroScanner == null) {
- return; // No Macros were provided
- }
- if (cachedStdMacros != null) { // no need to parse again
- for (int i = 0; i < cachedStdMacros.size(); i++) {
- KinTermDef macro = new KinTermDef((KinTermDef) cachedStdMacros.get(i));
- macro.domTh = dTheory;
- dTheory.theory.put(macro.kinTerm, macro);
- dTheory.nonTerms.add(macro.kinTerm);
- }
- return;
- }
- Tokenizer holdScan = scanner; // temporarily store the main Tokenizer & Linus
- Linus holdThatLine = lineMan; // I couldn't resist!
- TokenScanned priorCurrent = current;
- scanner = macroScanner; // Substitute the Macro Tokenizer & Linus
- lineMan = macroLineMan;
- current = scanner.lookAhead();
- KinTermDef ktd = parseKinTermDef();
- parseSignatureString(ktd);
- parseExpansion(ktd);
- for (int i = 0; i < ktd.expandedDefs.size(); i++) // number the expanded defintions
- {
- ((ClauseBody) ktd.expandedDefs.get(i)).seqNmbr = i;
- }
- parseOtherDefs();
- // All KTDs in the Macro file have been parsed & added; now put them in nonTerms List.
- Iterator ktdIter = dTheory.theory.values().iterator();
- cachedStdMacros = new ArrayList<Object>();
- while (ktdIter.hasNext()) {
- KinTermDef tempKTD = (KinTermDef) ktdIter.next();
- dTheory.nonTerms.add(tempKTD.kinTerm);
- cachedStdMacros.add(tempKTD);
- }
- scanner = holdScan; // Put back original Tokenizer & Linus
- lineMan = holdThatLine;
- current = priorCurrent;
- return;
- } // end of method parseStandardMacros
- public void parseStandardMacros(DomainTheory dt) throws KSParsingErrorException {
- // NOTE: This version of parseStandardMacros is meant to be called with a DomainTheory
- // that needs just the Std Macros added to it's theory.
- if (cachedStdMacros != null) { // no need to parse again
- for (int i = 0; i < cachedStdMacros.size(); i++) {
- KinTermDef macro = new KinTermDef((KinTermDef) cachedStdMacros.get(i));
- macro.domTh = dt;
- dt.theory.put(macro.kinTerm, macro);
- dt.nonTerms.add(macro.kinTerm);
- }
- return;
- }
- dTheory = dt;
- current = scanner.lookAhead();
- KinTermDef ktd = parseKinTermDef();
- parseSignatureString(ktd);
- parseExpansion(ktd);
- for (int i = 0; i < ktd.expandedDefs.size(); i++) // number the expanded defintions
- {
- ((ClauseBody) ktd.expandedDefs.get(i)).seqNmbr = i;
- }
- parseOtherDefs();
- // All KTDs in the Macro file have been parsed & added; now put them in nonTerms List.
- Iterator ktdIter = dTheory.theory.values().iterator();
- cachedStdMacros = new ArrayList<Object>();
- while (ktdIter.hasNext()) {
- KinTermDef tempKTD = (KinTermDef) ktdIter.next();
- dTheory.nonTerms.add(tempKTD.kinTerm);
- cachedStdMacros.add(tempKTD);
- }
- return;
- } // end of method parseStandardMacros
- // TermPairs -> TermPair, OtherTermPairs.
- // First: [leftParen] Follow: [rightParen]
- private void parseTermPairs(TreeMap tMap, boolean dblPost) throws KSParsingErrorException {
- parseTermPair(tMap, dblPost);
- parseOtherTermPairs(tMap, dblPost);
- } // end of method parseTermPairs
- // TermPair -> leftParen, symbol, comma, symbol, rightParen.
- // First: [leftParen] Follow: [comma, rightParen]
- private void parseTermPair(TreeMap tMap, boolean dblPost) throws KSParsingErrorException {
- current = scanner.readToken(); // consume next, which must be a leftParen
- if (!current.token.equals("leftParen")) {
- error("parseTermPair seeking a leftParen");
- }
- current = scanner.readToken(); // consume next, which must be a symbol
- if (!current.token.equals("symbol")) {
- error("parseTermPair seeking a symbol");
- }
- String term1 = current.lexeme;
- current = scanner.readToken(); // consume next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseTermPair seeking a comma");
- }
- current = scanner.readToken(); // consume next, which must be a symbol
- if (!current.token.equals("symbol")) {
- error("parseTermPair seeking a symbol");
- }
- String term2 = current.lexeme;
- current = scanner.readToken(); // consume next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseTermPair seeking a rightParen");
- }
- // all elements of the term pair are now validated. Post.
- if (dblPost) { // Overlaps are double-posted in a different structure
- if (tMap.get(term1) == null) {
- tMap.put(term1, new ArrayList<Object>());
- }
- ArrayList<Object> oLapList = (ArrayList<Object>) tMap.get(term1);
- oLapList.add(term2);
- if (tMap.get(term2) == null) {
- tMap.put(term2, new ArrayList<Object>());
- }
- oLapList = (ArrayList<Object>) tMap.get(term2);
- oLapList.add(term1);
- } else {
- tMap.put(term2, term1);
- }
- } // end of method parseTermPairs
- // OtherTermPairs -> comma, TermPair, OtherTermPairs.
- // | \empty.
- // First: [comma] Follow: [rightParen]
- private void parseOtherTermPairs(TreeMap tMap, boolean dblPost) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if ((!current.token.equals("comma"))
- && (!current.token.equals("rightParen"))) {
- error("parseOtherTermPairs seeking a comma or rightParen");
- }
- if (current.token.equals("rightParen")) {
- return;
- }
- scanner.readToken(); // consume the comma
- parseTermPair(tMap, dblPost);
- parseOtherTermPairs(tMap, dblPost);
- } // end of method parseOtherTermPairs
- // TermListPairs -> TermListPair, OtherTermListPairs.
- // First: [leftParen] Follow: [rightParen]
- private void parseTermListPairs(TreeMap tMap, boolean dblPost) throws KSParsingErrorException {
- parseTermListPair(tMap, dblPost);
- parseOtherTermListPairs(tMap, dblPost);
- } // end of method parseTermListPairs
- // OtherTermListPairs -> comma, TermListPair, OtherTermListPairs.
- // | \empty.
- // First: [comma] Follow: [rightParen]
- private void parseOtherTermListPairs(TreeMap tMap, boolean dblPost) throws KSParsingErrorException {
- current = scanner.lookAhead();
- if ((!current.token.equals("comma"))
- && (!current.token.equals("rightParen"))) {
- error("parseOtherTermListPairs seeking a comma or rightParen");
- }
- if (current.token.equals("rightParen")) {
- return;
- }
- scanner.readToken(); // consume the comma
- parseTermListPair(tMap, dblPost);
- parseOtherTermListPairs(tMap, dblPost);
- } // end of method parseOtherTermListPairs
- // TermListPair -> leftParen, symbol, comma, TermList, rightParen.
- // First: [leftParen] Follow: [rightParen]
- private void parseTermListPair(TreeMap tMap, boolean dblPost) throws KSParsingErrorException {
- current = scanner.readToken(); // consume next, which must be a leftParen
- if (!current.token.equals("leftParen")) {
- error("parseTermListPair seeking a leftParen");
- }
- current = scanner.readToken(); // consume next, which must be a symbol
- if (!current.token.equals("symbol")) {
- error("parseTermListPair seeking a symbol");
- }
- String baseTerm = current.lexeme;
- current = scanner.readToken(); // consume next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseTermListPair seeking a comma");
- }
- ArrayList<Object> termList = parseTermList();
- current = scanner.readToken(); // consume next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseTermListPair seeking a rightParen");
- }
- // all elements are validated. Post to tMap.
- if (dblPost) { // overlaps require double-posting; umbrellas do not
- if (tMap.get(baseTerm) == null) {
- tMap.put(baseTerm, new ArrayList<Object>());
- }
- ArrayList<Object> baseList = (ArrayList<Object>) tMap.get(baseTerm);
- for (int i = 0; i < termList.size(); i++) {
- String oLapTerm = (String) termList.get(i);
- if (tMap.get(oLapTerm) == null) {
- tMap.put(oLapTerm, new ArrayList<Object>());
- }
- ArrayList<Object> oLapTermList = (ArrayList<Object>) tMap.get(oLapTerm);
- if (!baseList.contains(oLapTerm)) {
- baseList.add(oLapTerm);
- }
- if (!oLapTermList.contains(baseTerm)) {
- oLapTermList.add(baseTerm);
- }
- } // end of loop thru all overlapping terms of baseTerm
- } else {
- tMap.put(baseTerm, termList);
- }
- } // end of method parseTermListPair
- // TermList -> leftParen, symbol, MoreTerms, rightParen.
- // First: [leftParen] Follow: [rightParen]
- private ArrayList<Object> parseTermList() throws KSParsingErrorException {
- current = scanner.readToken(); // consume next, which must be a leftParen
- if (!current.token.equals("leftParen")) {
- error("parseTermList seeking a leftParen");
- }
- current = scanner.readToken(); // consume next, which must be a symbol
- if (!current.token.equals("symbol")) {
- error("parseTermList seeking a symbol");
- }
- ArrayList<Object> termList = new ArrayList<Object>();
- termList.add(current.lexeme);
- current = scanner.lookAhead();
- if ((!current.token.equals("comma")) && (!current.token.equals("rightParen"))) {
- error("parseTermList seeking a comma or rightParen");
- }
- if (current.token.equals("comma")) {
- termList.addAll(parseMoreTerms());
- }
- current = scanner.readToken(); // consume next, which must be a rightParen
- if (!current.token.equals("rightParen")) {
- error("parseTermList seeking a rightParen");
- }
- return termList;
- } // end of method parseTermList
- // MoreTerms -> comma, symbol, MoreTerms.
- // | \empty.
- // First: [comma] Follow: [rightParen]
- private ArrayList<Object> parseMoreTerms() throws KSParsingErrorException {
- current = scanner.readToken(); // consume next, which must be a comma
- if (!current.token.equals("comma")) {
- error("parseMoreTerms seeking a comma");
- }
- current = scanner.readToken(); // consume next, which must be a symbol
- if (!current.token.equals("symbol")) {
- error("parseMoreTerms seeking a symbol");
- }
- ArrayList<Object> termList = new ArrayList<Object>();
- termList.add(current.lexeme);
- current = scanner.lookAhead();
- if ((!current.token.equals("comma")) && (!current.token.equals("rightParen"))) {
- error("parseMoreTerms seeking a comma or rightParen");
- }
- if (current.token.equals("comma")) {
- termList.addAll(parseMoreTerms());
- }
- return termList;
- } // end of method parseMoreTerms
- // Theory -> KinTermDef, SignatureString, (optional) string,
- // Expansion, OtherDefs.
- private void parseTheory() throws KSParsingErrorException {
- KinTermDef ktd = parseKinTermDef();
- parseSignatureString(ktd);
- current = scanner.lookAhead();
- if (current.token.equals("string")) {
- scanner.readToken(); // consume the string
- ktd.comments = curr…
Large files files are truncated, but you can click here to view the full file