Сложность использования грамматики JAPE - PullRequest
2 голосов
/ 22 сентября 2011

У меня есть документ, который содержит такие разделы, как оценки, HPI, ROS, Vitals и т. Д. Я хочу извлечь примечания в каждом разделе.Я использую GATE для этой цели.Я сделал файл JAPE, который будет извлекать заметки в разделе «Оценка».Ниже приведена грамматика:

Input: Token
Options: control=appelt debug=true

Rule: Assess
({Token.string =~"(?i)diagnose[d]?"}{Token.string=="with"} | {Token.string=~"(?i)suffering"}{Token.string=~"(?i)from"} | {Token.string=~"(?i)suffering"}{Token.string=~"(?i)with"})

(
({Token})*
):assessments

({Token.string =~"(?i)HPI"} | {Token.string =~"(?i)ROS"} | {Token.string =~"(?i)EXAM"} | {Token.string =~"(?i)VITAL[S]"} | {Token.string =~"(?i)TREATMENT[s]"} |{Token.string=~"(?i)use[d]?"}{Token.string=~"(?i)orderset[s]?"} | {Token.string=~"$"})


-->
:assessments.Assessments = {}

Теперь, когда раздел оценки находится в конце документа, я могу правильно получить примечания.Но если он находится где-то между двумя разделами, он вернет весь документ от раздела оценки до конца файла.

Я пытался использовать {Token.string = ~ "$"} по-разному, но не смог извлечь ТОЛЬКО В РАЗДЕЛЕ ОЦЕНКИ НЕЗНАЧИТЕЛЬНО ЕГО МЕСТО В ДОК* Пожалуйста, объясните, как я могу достичь этого, используя грамматику JAPE.

Ответы [ 2 ]

1 голос
/ 27 марта 2013

Это правильно, так как режим Appelt всегда предпочитает максимально длинный общий матч.Поскольку любой токен может совпадать с string =~ "$", метка assessments будет захватывать все, кроме последнего токена в документе.

Я бы применил двухпроходный подход, используя начальный заголовок или фазу JAPE для аннотирования раздела "заголовки ", а затем еще один этап с только этими аннотациями заголовков в строке ввода

Imports: { import static gate.Utils.*; }
Phase: AnnotateBetweenHeadings
Input: Heading
Options: control = appelt

Rule: TwoHeadings
({Heading.type ="assessments"}):h1
(({Heading})?):h2
-->
{
  Long endOffset = end(doc);
  AnnotationSet h2Annots = bindings.get("h2");
  if(h2Annots != null && !h2Annots.isEmpty()) {
    endOffset = start(h2Annots);
  }
  outputAS.add(end(bindings.get("h1")), endOffset, "Assessments", featureMap());
}

Это будет аннотировать все, что находится между концом заголовка оценки и началом следующего заголовка или концом документа, еслиследующего заголовка нет.

0 голосов
/ 27 марта 2013

Тайсон Гамильтон предоставляет эту альтернативу для аннотирования EOD, поскольку $ не работает в JAPE:

Rule: DOCMARKERS
// we need to match something even though we don't use it directly
(({Token})):doc
-->
:doc{
    FeatureMap features = Factory.newFeatureMap();
    features.put("rule", ruleName());

    try {
        outputAS.add(0L, 0L, "SOD", features);
        outputAS.add(docAnnots.getDocument().getContent().size(), docAnnots.getDocument().getContent().size(), "EOD", features);
    } catch (InvalidOffsetException ioe) {
        throw new GateRuntimeException(ioe);
    }
}

Я обнаружил, что EOD распознается только в более поздних правилах, давая ему некоторую длину. Итак, у меня есть это:

Rule: DOCMARKERS
Priority: 2
(
    ({Sentence}) // we need to matching something even though we don't use it directly
):doc
-->
:doc{
    FeatureMap features = Factory.newFeatureMap();
    features.put("rule", "DOCMARKERS");

    try {
        outputAS.add(0L, 0L, "SOD", features);
        long docsize = docAnnots.getDocument().getContent().size();
        // The only way I could get EOD to be recognized in later rules was to
        // give it some length, hence the -2 and -1
        outputAS.add(docsize-2, docsize-1, "EOD", features);
        System.err.println("Debug: added EOD");
    } catch (InvalidOffsetException ioe) {
        throw new GateRuntimeException(ioe);
    }
}

И тогда вы сможете изменить конец своего правила на

...| {Token.string=~"$"})
...