/* * name.jape * * Copyright (c) 1998-2004, The University of Sheffield. * * This file is part of GATE (see http://gate.ac.uk/), and is free * software, licenced under the GNU Library General Public License, * Version 2, June 1991 (in the distribution as file licence.html, * and also available at http://gate.ac.uk/gate/licence.html). * * Diana Maynard, 10 Sep 2001 * * $Id: name.jape,v 1.32 2005/10/26 09:03:09 dgmaynard Exp $ */ Phase: Name Input: Token Lookup Title FirstPerson Options: control = appelt debug = false /////////////////////////////////////////////////////////////// // Person Rules ///////////////////////////////////////////////////////////////// Macro: TITLE ( {Title} ({Token.string == "."})? ) Macro: INITIALS ( ({Token.orth == upperInitial, Token.length =="1"} ({Token.string == "."})? )+ ) Macro: INITIALS2 ( {Token.orth == allCaps, Token.length == "2"} | {Token.orth == allCaps, Token.length == "3"} ) Macro: FIRSTNAME ( ({FirstPerson.gender == male} | {FirstPerson.gender == female}) | (INITIALS) ) Macro: FIRSTNAMEAMBIG ( {Lookup.majorType == person_first, Lookup.minorType == ambig} ) Macro: UPPER ( ({Token.category == NNP}| {Token.orth == upperInitial}| {Token.orth == mixedCaps} ) ({Token.string == "-"} {Token.category == NNP} )? ) Macro: PERSONENDING ( {Lookup.majorType == person_ending} ) Macro: PREFIX ( ({Lookup.majorType == surname, Lookup.minorType == prefix} )| (({Token.string == "O"}|{Token.string == "D"}) {Token.string == "'"} ) ) /////////////////////////////////////////////////////////// // Person Rules Rule: Pronoun Priority: 1000 //stops personal pronouns being recognised as Initials ( {Token.category == PP}| {Token.category == PRP}| {Token.category == RB} ):pro --> {} Rule: GazPerson Priority: 50 ( {Lookup.majorType == person_full} ) :person --> { gate.AnnotationSet person = (gate.AnnotationSet)bindings.get("person"); gate.Annotation personAnn = (gate.Annotation)person.iterator().next(); gate.FeatureMap features = Factory.newFeatureMap(); features.put("kind", "personName"); features.put("rule", "GazPerson"); annotations.add(person.firstNode(), person.lastNode(), "TempPerson", features); } Rule: TheGazPersonFirst Priority: 200 ( {Token.category == DT}| {Token.category == PRP}| {Token.category == RB} ) ( {FirstPerson} ) :person ( {Token.orth == upperInitial, Token.length == "1"} )? --> { gate.AnnotationSet person = (gate.AnnotationSet)bindings.get("person"); gate.Annotation personAnn = (gate.Annotation)person.iterator().next(); gate.FeatureMap features = Factory.newFeatureMap(); features.put("gender", personAnn.getFeatures().get("gender")); features.put("kind", "personName"); features.put("rule", "GazPersonFirst"); annotations.add(person.firstNode(), person.lastNode(), "TempPerson", features); //annotations.removeAll(person); } Rule: GazPersonFirst Priority: 70 ( {FirstPerson} ) :person ( {Token.orth == upperInitial, Token.length == "1"} )? --> { gate.AnnotationSet person = (gate.AnnotationSet)bindings.get("person"); gate.Annotation personAnn = (gate.Annotation)person.iterator().next(); gate.FeatureMap features = Factory.newFeatureMap(); features.put("gender", personAnn.getFeatures().get("gender")); features.put("kind", "personName"); features.put("rule", "GazPersonFirst"); annotations.add(person.firstNode(), person.lastNode(), "TempPerson", features); //annotations.removeAll(person); } Rule: PersonFirstContext Priority: 30 // Anne and Kenton ( {FirstPerson} ):person1 ( {Token.string == "and"} ) ({Token.orth == upperInitial}) :person2 --> { //first deal with person1 gate.FeatureMap features1 = Factory.newFeatureMap(); gate.AnnotationSet person1Set = (gate.AnnotationSet)bindings.get("person1"); gate.AnnotationSet firstPerson = (gate.AnnotationSet)person1Set.get("FirstPerson"); if (firstPerson != null && firstPerson.size()>0) { gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features1.put("gender", personAnn.getFeatures().get("gender")); } features1.put("kind", "personName"); features1.put("rule", "PersonFirstContext"); annotations.add(person1Set.firstNode(), person1Set.lastNode(), "TempPerson", features1); //now deal with person2 gate.FeatureMap features2 = Factory.newFeatureMap(); gate.AnnotationSet person2Set = (gate.AnnotationSet)bindings.get("person2"); features2.put("kind", "personName"); features2.put("rule", "PersonFirstContext"); annotations.add(person2Set.firstNode(), person2Set.lastNode(), "TempPerson", features2); } Rule: PersonFirstContext2 Priority: 40 // Anne and I ( {FirstPerson} ):person ( {Token.string == "and"} {Token.length == "1"} ) --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); gate.AnnotationSet firstPerson = (gate.AnnotationSet)personSet.get("FirstPerson"); if (firstPerson != null && firstPerson.size()>0) { gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } features.put("kind", "personName"); features.put("rule", "PersonFirstContext2"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonTitle Priority: 35 // Mr. Jones // Mr Fred Jones // note we only allow one first and surname, // but we can add more in a final phase if we find adjacent unknowns ( {Token.category == DT}| {Token.category == PRP}| {Token.category == RB} )? ( (TITLE)+ ((FIRSTNAME | FIRSTNAMEAMBIG | INITIALS2) )? (PREFIX)* (UPPER) (PERSONENDING)? ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); // get all Title annotations that have a gender feature HashSet fNames = new HashSet(); fNames.add("gender"); gate.AnnotationSet personTitle = personSet.get("Title", fNames); // if the gender feature exists if (personTitle != null && personTitle.size()>0) { //Out.prln("Titles found " + personTitle); gate.Annotation personAnn = (gate.Annotation)personTitle.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } else { //get all firstPerson annotations that have a gender feature // HashSet fNames = new HashSet(); // fNames.add("gender"); gate.AnnotationSet firstPerson = personSet.get("FirstPerson", fNames); if (firstPerson != null && firstPerson.size()>0) { //Out.prln("First persons found " + firstPerson); gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } } features.put("kind", "personName"); features.put("rule", "PersonTitle"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonFirstTitleGender Priority: 55 // use this rule when we know what gender the title indicates // Mr Fred ( ({Title.gender == male} | {Title.gender == female}) ((FIRSTNAME | FIRSTNAMEAMBIG | INITIALS2) ) ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); gate.AnnotationSet title = (gate.AnnotationSet)personSet.get("Title"); if (title != null && title.size()>0) { gate.Annotation personAnn = (gate.Annotation)title.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } features.put("kind", "personName"); features.put("rule", "PersonFirstTitleGender"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonTitleGender Priority: 18 // use this rule if the title has a feature gender // Miss F Smith ( ({Title.gender == male}| {Title.gender == female} ) ((FIRSTNAME | FIRSTNAMEAMBIG | INITIALS2) )* (UPPER) (PERSONENDING)? ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); gate.AnnotationSet title = (gate.AnnotationSet)personSet.get("Title"); // if the annotation type title doesn't exist, do nothing if (title != null && title.size()>0) { // if it does exist, take the first element in the set gate.Annotation personAnn = (gate.Annotation)title.iterator().next(); //propagate gender feature (and value) from title features.put("gender", personAnn.getFeatures().get("gender")); } // create some new features features.put("kind", "personName"); features.put("rule", "PersonTitleGender"); // create a TempPerson annotation and add the features we've created annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonJobTitle Priority: 20 // note we include titles but not jobtitles in markup ( {Lookup.majorType == jobtitle} ):jobtitle ( (TITLE)? ((FIRSTNAME | FIRSTNAMEAMBIG | INITIALS2) ) (PREFIX)* (UPPER) (PERSONENDING)? ) :person --> :person.TempPerson = {kind = "personName", rule = "PersonJobTitle"}, :jobtitle.JobTitle = {rule = "PersonJobTitle"} Rule: NotFirstPersonStop Priority: 50 // ambig first name and surname is stop word // e.g. Will And ( ((FIRSTNAMEAMBIG)+ | {Token.category == PRP}| {Token.category == DT} ) ({Lookup.majorType == stop} ) ) :person --> {} Rule: FirstPersonStop Priority: 50 // John And ( {FirstPerson} ):person ( {Token.category == DT}| {Token.category == PRP}| {Token.category == RB}| {Token.category == IN} ) --> { gate.AnnotationSet person = (gate.AnnotationSet)bindings.get("person"); gate.Annotation personAnn = (gate.Annotation)person.iterator().next(); gate.FeatureMap features = Factory.newFeatureMap(); features.put("gender", personAnn.getFeatures().get("gender")); features.put("kind", "personName"); features.put("rule", "GazPersonFirst"); annotations.add(person.firstNode(), person.lastNode(), "TempPerson", features); } Rule: NotPersonFull Priority: 50 // do not allow Det + Surname ( {Token.category == DT}| {Token.category == PRP}| {Token.category == RB} ) ( (PREFIX)* (UPPER) (PERSONENDING)? ):foo --> {} Rule: LocPersonAmbig Priority: 50 // Location + Surname ( {Lookup.majorType == location} ):loc ( (PREFIX)* (UPPER) (PERSONENDING)? ):foo --> :loc.TempLocation = {kind = "locName", rule = LocPersonAmbig} Rule: PersonFull Priority: 10 // F.W. Jones // Fred Jones ( {Token.category == DT} )? ( ((FIRSTNAME | FIRSTNAMEAMBIG) )+ (PREFIX)* (UPPER) (PERSONENDING)? ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); //get all firstPerson annotations that have a gender feature HashSet fNames = new HashSet(); fNames.add("gender"); gate.AnnotationSet firstPerson = personSet.get("FirstPerson", fNames); if (firstPerson != null && firstPerson.size()>0) { //Out.prln("First persons found " + firstPerson); gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } features.put("kind", "personName"); features.put("rule", "PersonFull"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonFullStop Priority: 50 // G.Wilson Fri ( ((FIRSTNAME | FIRSTNAMEAMBIG) ) (PREFIX)* (UPPER) ):person ( {Lookup.majorType == date} ) --> :person.TempPerson = {kind = "personName", rule = "PersonFullStop"} Rule: NotPersonFullReverse Priority: 20 // XYZ, I ( (UPPER) {Token.string == ","} {Token.category == PRP} (PERSONENDING)? ) :unknown --> {} Rule: PersonFullReverse Priority: 5 // Jones, F.W. // don't allow Jones, Fred because too ambiguous // Smith, TF ( {Token.category ==NNP} {Token.string == ","} (INITIALS )+ (PERSONENDING)? ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); gate.AnnotationSet firstPerson = (gate.AnnotationSet)personSet.get("FirstPerson"); if (firstPerson != null && firstPerson.size()>0) { gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } features.put("kind", "personName"); features.put("rule", "PersonFullReverse"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonSaint Priority: 50 // Note: ensure that it's not a Saints Day first ( ({Token.string == "St"} ({Token.string == "."})? | {Token.string == "Saint"}) (FIRSTNAME) ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); gate.AnnotationSet firstPerson = (gate.AnnotationSet)personSet.get("FirstPerson"); if (firstPerson != null && firstPerson.size()>0) { gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } features.put("kind", "personName"); features.put("rule", "PersonSaint"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } Rule: PersonLocAmbig Priority: 40 // Ken London // Susan Hampshire // Christian name + Location --> Person's Name ( ({Lookup.majorType == person_first} | (INITIALS {Token.string == "."}) ) {Lookup.majorType == location} ) :person --> { gate.FeatureMap features = Factory.newFeatureMap(); gate.AnnotationSet personSet = (gate.AnnotationSet)bindings.get("person"); gate.AnnotationSet firstPerson = (gate.AnnotationSet)personSet.get("FirstPerson"); if (firstPerson != null && firstPerson.size()>0) { gate.Annotation personAnn = (gate.Annotation)firstPerson.iterator().next(); features.put("gender", personAnn.getFeatures().get("gender")); } features.put("kind", "personName"); features.put("rule", "PersonLocAmbig"); annotations.add(personSet.firstNode(), personSet.lastNode(), "TempPerson", features); } /////////////////////////////////////////////////////////////////// // Organisation Rules Macro: CDG // cdg is something like "Ltd." ( ({Lookup.majorType == cdg})| ({Token.string == ","} {Lookup.majorType == cdg}) ) Macro: SAINT ( ({Token.string == "St"} ({Token.string == "."})? | {Token.string == "Saint"}) ) Macro: CHURCH ( {Token.string == "Church"}|{Token.string == "church"}| {Token.string == "Cathedral"}|{Token.string == "cathedral"}| {Token.string == "Chapel"}|{Token.string == "chapel"} ) ///////////////////////////////////////////////////////////// Rule: TheGazOrganization Priority: 245 ( {Token.category == DT}| {Token.category == RB} ) ( {Lookup.majorType == organization} ) :orgName --> { gate.FeatureMap features = Factory.newFeatureMap(); // create an annotation set consisting of all the annotations for org gate.AnnotationSet orgSet = (gate.AnnotationSet)bindings.get("orgName"); // create an annotation set consisting of the annotation matching Lookup gate.AnnotationSet org = (gate.AnnotationSet)orgSet.get("Lookup"); // if the annotation type Lookup doesn't exist, do nothing if (org != null && org.size()>0) { // if it does exist, take the first element in the set gate.Annotation orgAnn = (gate.Annotation)org.iterator().next(); //propagate minorType feature (and value) from org features.put("orgType", orgAnn.getFeatures().get("minorType")); } // create some new features features.put("rule", "GazOrganization"); // create a TempOrg annotation and add the features we've created annotations.add(orgSet.firstNode(), orgSet.lastNode(), "TempOrganization", features); } Rule: GazOrganization Priority: 145 ( {Lookup.majorType == organization} ) :orgName --> { gate.FeatureMap features = Factory.newFeatureMap(); // create an annotation set consisting of all the annotations for org gate.AnnotationSet orgSet = (gate.AnnotationSet)bindings.get("orgName"); // create an annotation set consisting of the annotation matching Lookup gate.AnnotationSet org = (gate.AnnotationSet)orgSet.get("Lookup"); // if the annotation type Lookup doesn't exist, do nothing if (org != null && org.size()>0) { // if it does exist, take the first element in the set gate.Annotation orgAnn = (gate.Annotation)org.iterator().next(); //propagate minorType feature (and value) from org features.put("orgType", orgAnn.getFeatures().get("minorType")); } // create some new features features.put("rule", "GazOrganization"); // create a TempOrg annotation and add the features we've created annotations.add(orgSet.firstNode(), orgSet.lastNode(), "TempOrganization", features); } Rule: LocOrganization Priority: 50 // Ealing Police ( ({Lookup.majorType == location} | {Lookup.majorType == country_adj}) {Lookup.majorType == organization} ({Lookup.majorType == organization})? ) :orgName --> :orgName.TempOrganization = {kind = "orgName", rule=LocOrganization} Rule: INOrgXandY Priority: 200 // Bradford & Bingley // Bradford & Bingley Ltd ( {Token.category == IN} ) ( ({Token.category == NNP} )+ {Token.string == "&"} ( {Token.orth == upperInitial} )+ (CDG)? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXandY"} Rule: OrgXandY Priority: 20 // Bradford & Bingley // Bradford & Bingley Ltd ( ({Token.category == NNP} )+ {Token.string == "&"} ( {Token.orth == upperInitial} )+ (CDG)? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXandY"} Rule:OrgUni Priority: 25 // University of Sheffield // Sheffield University // A Sheffield University ( {Token.string == "University"} {Token.string == "of"} ( {Token.category == NNP})+ ) :orgName --> :orgName.TempOrganization = {kind = "org", rule = "OrgDept"} Rule: OrgDept Priority: 25 // Department of Pure Mathematics and Physics ( {Token.string == "Department"} {Token.string == "of"} ( {Token.orth == upperInitial})+ ( {Token.string == "and"} ( {Token.orth == upperInitial})+ )? ) :orgName --> :orgName.TempOrganization = {kind = "department", rule = "OrgDept"} Rule: TheOrgXKey Priority: 500 // The Aaaa Ltd. ( {Token.category == DT} ) ( (UPPER) (UPPER)? (UPPER)? (UPPER)? (UPPER)? {Lookup.majorType == org_key} ({Lookup.majorType == org_ending})? ) :org --> :org.TempOrganization = {kind = "unknown", rule = "TheOrgXKey"} Rule: OrgXKey Priority: 125 // Aaaa Ltd. ( (UPPER) (UPPER)? (UPPER)? (UPPER)? (UPPER)? {Lookup.majorType == org_key} ({Lookup.majorType == org_ending})? ) :org --> :org.TempOrganization = {kind = "unknown", rule = "TheOrgXKey"} Rule: NotOrgXEnding Priority: 500 // Very Limited ( {Token.category == DT} )? ( {Token.category == RB} {Lookup.majorType == cdg} ) :label --> {} Rule: NotOrgXEnding2 Priority: 500 // The Coca Cola Co. ( {Token.category == DT} ) ( (UPPER) (UPPER)? {Lookup.majorType == cdg} ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXEnding"} Rule: OrgXEnding Priority: 120 // Coca Cola Co. ( (UPPER) (UPPER)? {Lookup.majorType == cdg} ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXEnding"} Rule: TheOrgXandYKey Priority: 220 ( {Token.category == DT} ) ( (UPPER) (UPPER)? (({Token.string == "and"} | {Token.string == "&"}) (UPPER)? (UPPER)? (UPPER)? ) {Lookup.majorType == org_key} ({Lookup.majorType == org_ending})? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXandYKey"} Rule: OrgXandYKey Priority: 120 // Aaaa Ltd. // Xxx Services Ltd. // AA and BB Services Ltd. // but NOT A XXX Services Ltd. ( (UPPER) (UPPER)? (({Token.string == "and"} | {Token.string == "&"}) (UPPER)? (UPPER)? (UPPER)? ) {Lookup.majorType == org_key} ({Lookup.majorType == org_ending})? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXandYKey"} Rule: OrgXsKeyBase Priority: 120 // Gandy's Circus // Queen's Ware ( (UPPER)? (UPPER)? ({Token.orth == upperInitial} {Token.string == "'"} ({Token.string == "s"})? ) ({Lookup.majorType == org_key}| {Lookup.majorType == org_base}) ) :orgName --> :orgName.TempOrganization = {kind = "org", rule = "OrgXsKeybase"} Rule: NotOrgXBase Priority: 1000 // not things like British National // or The University ( ({Token.category == DT} )? ) ( ({Lookup.majorType == country_adj}| {Token.orth == lowercase}) ({Lookup.majorType == org_base}| {Lookup.majorType == govern_key}) ) :orgName --> :orgName.Temp = {kind = "notorgName", rule = "NotOrgXBase"} Rule: TheOrgXBase Priority: 230 ( ({Token.category == DT} ) ) ( ( (UPPER)| {Lookup.majorType == organization} ) (UPPER)? (UPPER)? ({Lookup.majorType == org_base}| {Lookup.majorType == govern_key} ) ( {Token.string == "of"} (UPPER) (UPPER)? (UPPER)? )? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "TheOrgXBase"} Rule: OrgXBase Priority: 130 // same as OrgXKey but uses base instead of key // includes govern_key e.g. academy // Barclays Bank // Royal Academy of Art ( ( (UPPER)| {Lookup.majorType == organization} ) (UPPER)? (UPPER)? ({Lookup.majorType == org_base}| {Lookup.majorType == govern_key} ) ( {Token.string == "of"} (UPPER) (UPPER)? (UPPER)? )? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgXBase"} Rule: TheBaseofOrg Priority: 230 ( {Token.category == DT} ) ( ({Lookup.majorType == org_base}| {Lookup.majorType == govern_key} ) {Token.string == "of"} ( {Token.category == DT} )? (UPPER) (UPPER)? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "BaseofOrg"} Rule: BaseofOrg Priority: 130 ( ({Lookup.majorType == org_base}| {Lookup.majorType == govern_key} ) {Token.string == "of"} ( {Token.category == DT} )? (UPPER) (UPPER)? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "BaseofOrg"} Rule: OrgPreX Priority: 130 // Royal Tuscan ( {Lookup.majorType == org_pre} ( {Token.orth == upperInitial})+ ({Lookup.majorType == org_ending})? ) :orgName --> :orgName.TempOrganization = {kind = "unknown", rule = "OrgPreX"} Rule: OrgChurch Priority: 150 // St. Andrew's Church ( (SAINT) {Token.orth == upperInitial} {Token.string == "'"}({Token.string == "s"})? (CHURCH) ) :orgName --> :orgName.TempOrganization = {kind = "org", rule = "OrgChurch"} Rule:OrgPersonAmbig Priority: 130 // Alexandra Pottery should be org not person // overrides PersonFull ( (FIRSTNAME) ({Lookup.majorType == org_key}| {Lookup.majorType == org_base}) ({Lookup.majorType == org_ending})? ) :org --> :org.TempOrganization= {kind = "unknown", rule = "OrgPersonAmbig"} ///////////////////////////////////////////////////////////////// // Location rules Rule: Location1 Priority: 75 // Lookup = city, country, province, region, water // Western Europe // South China sea ( {Token.category == DT} )? ( ({Lookup.majorType == loc_key, Lookup.minorType == pre} )? {Lookup.majorType == location} ( {Lookup.majorType == loc_key, Lookup.minorType == post})? ) :locName --> { gate.FeatureMap features = Factory.newFeatureMap(); // create an annotation set consisting of all the annotations for org gate.AnnotationSet locSet = (gate.AnnotationSet)bindings.get("locName"); // create an annotation set consisting of the annotation matching Lookup gate.AnnotationSet loc = (gate.AnnotationSet)locSet.get("Lookup"); // if the annotation type Lookup doesn't exist, do nothing if (loc != null && loc.size()>0) { // if it does exist, take the first element in the set gate.Annotation locAnn = (gate.Annotation)loc.iterator().next(); //propagate minorType feature (and value) from loc features.put("locType", locAnn.getFeatures().get("minorType")); } // create some new features features.put("rule", "Location1"); // create a TempLoc annotation and add the features we've created annotations.add(locSet.firstNode(), locSet.lastNode(), "TempLocation", features); } Rule: GazLocation Priority: 70 ( {Token.category == DT} )? ( {Lookup.majorType == location} ) :locName --> { gate.FeatureMap features = Factory.newFeatureMap(); // create an annotation set consisting of all the annotations for org gate.AnnotationSet locSet = (gate.AnnotationSet)bindings.get("locName"); // create an annotation set consisting of the annotation matching Lookup gate.AnnotationSet loc = (gate.AnnotationSet)locSet.get("Lookup"); // if the annotation type Lookup doesn't exist, do nothing if (loc != null && loc.size()>0) { // if it does exist, take the first element in the set gate.Annotation locAnn = (gate.Annotation)loc.iterator().next(); //propagate minorType feature (and value) from loc features.put("locType", locAnn.getFeatures().get("minorType")); } // create some new features features.put("rule", "GazLocation"); // create a TempLoc annotation and add the features we've created annotations.add(locSet.firstNode(), locSet.lastNode(), "TempLocation", features); } Rule: LocationPost Priority: 50 ( {Token.category == DT} )? ( {Token.category == NNP} {Lookup.majorType == loc_key, Lookup.minorType == post} ) :locName --> :locName.TempLocation = {kind = "locName", rule = LocationPost} Rule:LocKey ( {Token.category == DT} )? ( ({Lookup.majorType == loc_key, Lookup.minorType == pre} ) (UPPER) ( {Lookup.majorType == loc_key, Lookup.minorType == post})? ) :locName --> :locName.TempLocation = {kind = "locName", rule = LocKey} ///////////////////////////////////////////////////////////////// // Context-based Rules Rule:InLoc1 ( {Token.string == "in"} ) ( {Lookup.majorType == location} ) :locName --> :locName.TempLocation = {kind = "locName", rule = InLoc1} Rule:LocGeneralKey Priority: 30 ( {Lookup.majorType == loc_general_key} {Token.string == "of"} ) ( (UPPER) ) :loc --> :loc.TempLocation = {kind = "locName", rule = LocGeneralKey} Rule:OrgContext1 Priority: 1 // company X ( {Token.string == "company"} ) ( (UPPER) (UPPER)? (UPPER)? ) :org --> :org.TempOrganization= {kind = "orgName", rule = "OrgContext1"} Rule: OrgContext2 Priority: 5 // Telstar laboratory // Medici offices ( (UPPER) (UPPER)? (UPPER)? ) : org ( ({Token.string == "offices"} | {Token.string == "Offices"} | {Token.string == "laboratory"} | {Token.string == "Laboratory"} | {Token.string == "laboratories"} | {Token.string == "Laboratories"}) ) --> :org.TempOrganization= {kind = "orgName", rule = "OrgContext2"} Rule:JoinOrg Priority: 50 // Smith joined Energis ( ({Token.string == "joined"}| {Token.string == "joining"}| {Token.string == "joins"}| {Token.string == "join"} ) ) ( (UPPER) (UPPER)? (UPPER)? ) :org --> :org.TempOrganization= {kind = "orgName", rule = "joinOrg"}