Лексер Antlr 4 с несколькими режимами не может правильно токенизировать

Я пытаюсь создать лексер с несколькими режимами, используя Antlr 4.7. Мой лексер в настоящее время:

ACTIONONLY  : 'AO'; 

BELIEFS :   ':Initial Beliefs:' -> mode(INITIAL_BELIEFS);
NAME    :   ':name:';
WORD:   ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+;

COMMENT : '/*' .*? '*/' -> skip ;
LINE_COMMENT : '//' ~[\n]* -> skip ;
NEWLINE:'\r'? '\n' -> skip  ;
WS  :   (' '|'\t') -> skip ;

mode INITIAL_BELIEFS;
GOAL_IB :   ':Initial Goal:' -> mode(GOALS);
IB_COMMENT : '/*' .*? '*/' -> skip ;
IB_LINE_COMMENT : '//' ~[\n]* -> skip ;
IB_NEWLINE:'\r'? '\n' -> skip  ;
IB_WS  :   (' '|'\t') -> skip ;
BELIEF_BLOCK: ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'('|')'|','|'.')+;

mode REASONING_RULES;
R1: 'a';
R2: 'b';

mode GOALS;
GL_COMMENT : '/*' .*? '*/' -> skip ;
GL_LINE_COMMENT : '//' ~[\n]* -> skip ;
GL_NEWLINE:'\r'? '\n' -> skip  ;
GL_WS  :   (' '|'\t') -> skip ;
GOAL_BLOCK: ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'('|')'|','|'.')+;

Обратите внимание, что в настоящее время нет возможности перейти в режим REASONING_RULES (так что это не должно, насколько я понимаю, влиять на работу лексера). Очевидно, я хочу использовать этот режим, но это минимальная версия лексера, которая, кажется, отображает мою проблему.

Мой парсер:

grammar ActionOnly;

options { tokenVocab = ActionOnlyLexer; }

// Mas involving ActionOnly Agents
mas  :  aoagents;

aoagents: ACTIONONLY (aoagent)+;

// Agent stuff
aoagent  : 
    (ACTIONONLY?) 
    NAME w=WORD  
    BELIEFS (bs=BELIEF_BLOCK )?
    GOAL_IB gs=GOAL_BLOCK;

и я пытаюсь разобрать:

AO

:name: robot

:Initial Beliefs:

abelief

:Initial Goal:

at(4, 2)

Это не с ошибкой

строка 35: 0 несоответствующий ввод 'в (4,' ожидает GOAL_BLOCK

что, как я предполагаю, связано с тем, что токенизация не выполняется правильно.

Если я опущу правило R2 в режиме REASONING_RULES, оно будет правильно проанализировано (в общем, мне кажется, что у меня есть одно правило в REASONING_RULES, и оно будет работать, но более одного правила, и оно не соответствует GOAL_BLOCK)

Я действительно изо всех сил пытаюсь понять, что я здесь делаю неправильно, но это первый раз, когда я пробовал использовать режимы лексера с Antlr.


person Louise Dennis    schedule 16.08.2017    source источник


Ответы (1)


Я не получаю этой ошибки, когда пробую вашу грамматику. Я также тестировал с ANTLR 4.7.

Вот моя испытательная установка:

import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;

public class Main {

    public static void main(String[] args) {

        String source = "AO\n" +
                "\n" +
                ":name: robot\n" +
                "\n" +
                ":Initial Beliefs:\n" +
                "\n" +
                "abelief\n" +
                "\n" +
                ":Initial Goal:\n" +
                "\n" +
                "at(4, 2)";

        ActionOnlyLexer lexer = new ActionOnlyLexer(CharStreams.fromString(source));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        tokens.fill();

        System.out.println("[TOKENS]");

        for (Token t : tokens.getTokens()) {
            System.out.printf("  %-20s %s\n", ActionOnlyLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
        }

        System.out.println("\n[PARSE-TREE]");

        ActionOnlyParser parser = new ActionOnlyParser(tokens);
        ParserRuleContext context = parser.mas();

        System.out.println("  "+context.toStringTree(parser));
    }
}

И это выводится на мою консоль:

[TOKENS]
  ACTIONONLY           AO
  NAME                 :name:
  WORD                 robot
  BELIEFS              :Initial Beliefs:
  BELIEF_BLOCK         abelief
  GOAL_IB              :Initial Goal:
  GOAL_BLOCK           at(4,
  GOAL_BLOCK           2)
  EOF                  <EOF>

[PARSE-TREE]
  (mas (aoagents AO (aoagent :name: robot :Initial Beliefs: abelief :Initial Goal: at(4,)))

Возможно, вам нужно сгенерировать новые классы лексера / парсера?

PS. обратите внимание, что ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'('|')'|','|'.')+ можно записать как [a-zA-Z0-9_(),.]+

person Bart Kiers    schedule 16.08.2017
comment
Ты прав. Я переключил компьютер, и он работал, а затем я вручную очистил скомпилированные и сгенерированные файлы на исходном компьютере, и это тоже сработало. Я не уверен, как мне удавалось иметь устаревшие файлы и классы, так как я думал, что каждый раз перестраиваю все (подозреваю, что в моей настройке Eclipse есть какая-то странность). Спасибо за помощь! - person Louise Dennis; 17.08.2017