antlr4: Как сохранить комментарии в дереве разбора? [Дубликат]

Эта ошибка обычно возникает, когда вы пытаетесь прочитать файл, используя неправильную кодировку. Но, учитывая очень высокое смещение в вашем случае, также возможно, что у вас есть правильная кодировка, но какая-то ошибка в файле - нет смысла размышлять над спецификой.

Поскольку файл кажется в основном правильно, я могу просто попросить необработанные байты заменить специальным символом '�' (Unicode "\ufffd"). Затем вы можете найти контекст ошибки, просто выполнив поиск этого символа.

f = open('FY16_Query_Analysis1.txt', errors="replace")
raw = f.read()
lines = raw.splitlines()
for line in lines:
    if '�' in line:
        print(line)

В зависимости от того, что вы видите, вы можете решить, что делать дальше.

Альтернативно, вы мог прочитать файл в двоичном режиме и преобразовать строку вокруг рассматриваемого смещения; например:

f=open('FY16_Query_Analysis1.txt','rb')
raw = f.read()

errorpos = 16592600
fragment = raw[errorpos-20:errorpos+40]
print(repr(fragment))
3
задан T Suds 18 September 2012 в 22:14
поделиться

6 ответов

Есть ли способ сделать ANTLR автоматически добавлять любые комментарии, которые он находит в AST?

Нет, вам придется посыпать всю грамматику дополнительными правилами comments, чтобы учесть все допустимые места, которые могут возникнуть в комментариях:

...

if_stat
 : 'if' comments '(' comments expr comments ')' comments ...
 ;

...

comments
 : (SingleLineComment | MultiLineComment)*
 ;

SingleLineComment
 : '//' ~('\r' | '\n')*
 ;

MultiLineComment
 : '/*' .* '*/'
 ;
7
ответ дан Bart Kiers 21 August 2018 в 11:53
поделиться
  • 1
    Вот что я понял. Ну что ж. Реальная проблема заключается в том, что комментарии могут быть в любом месте исходного кода, поэтому каждое правило должно иметь «комментарии» & quot; в каждой его части. – T Suds 19 September 2012 в 15:00
  • 2
    @TSuds, да, это правильно. Обратите внимание, что поскольку мое правило comments не соответствует никаким или более комментариям, после него ? не требуется. – Bart Kiers 19 September 2012 в 15:06

Я сделал это на моей лексерской части:

WS  :   ( [ \t\r\n] | COMMENT) -> skip
;

fragment
COMMENT
: '/*'.*'*/' /*single comment*/
| '//'~('\r' | '\n')* /* multiple comment*/
;

Как будто он автоматически удалит их!

0
ответ дан Damiii 21 August 2018 в 11:53
поделиться

сначала: направить все комментарии на определенный канал (только комментарии)

COMMENT
    : '/*' .*? '*/' -> channel(2)
    ;

LINE_COMMENT
    : '//' ~[\r\n]* -> channel(2)
    ;

second: распечатать все комментарии

      CommonTokenStream tokens = new CommonTokenStream(lexer);
      tokens.fill();
      for (int index = 0; index < tokens.size(); index++)
      {
         Token token = tokens.get(index);
         // substitute whatever parser you have
         if (token.getType() != Parser.WS) 
         {
            String out = "";
            // Comments will be printed as channel 2 (configured in .g4 grammar file)
            out += "Channel: " + token.getChannel();
            out += " Type: " + token.getType();
            out += " Hidden: ";
            List<Token> hiddenTokensToLeft = tokens.getHiddenTokensToLeft(index);
            for (int i = 0; hiddenTokensToLeft != null && i < hiddenTokensToLeft.size(); i++)
            {
               if (hiddenTokensToLeft.get(i).getType() != IDLParser.WS)
               {
                  out += "\n\t" + i + ":";
                  out += "\n\tChannel: " + hiddenTokensToLeft.get(i).getChannel() + "  Type: " + hiddenTokensToLeft.get(i).getType();
                  out += hiddenTokensToLeft.get(i).getText().replaceAll("\\s", "");
               }
            }
            out += token.getText().replaceAll("\\s", "");
            System.out.println(out);
         }
      }
2
ответ дан Duncan Calvert 21 August 2018 в 11:53
поделиться

Для ANTLR v3:

Имена прожекторов обычно не обрабатываются парсером, но они все еще захватываются на канале HIDDEN.

Если вы используете BufferedTokenStream, вы можете получить список всех токенов через него и выполнить постобработку, добавив их по мере необходимости.

0
ответ дан Jiri Tousek 21 August 2018 в 11:53
поделиться

В разделе 12.1 в «Определяющем описании Antlr 4» показано, как получить доступ к комментариям, не используя правила комментариев во всей грамматике. Короче говоря, вы добавляете это в файл грамматики:

grammar Java;

@lexer::members {
    public static final int WHITESPACE = 1;
    public static final int COMMENTS = 2;
}

. Тогда для ваших правил комментариев выполните следующее:

COMMENT
    : '/*' .*? '*/' -> channel(COMMENTS)
    ;

LINE_COMMENT
    : '//' ~[\r\n]* -> channel(COMMENTS)
    ;

Затем в коде запросите токены через getHiddenTokensToLeft / getHiddenTokensToRight и посмотрите раздел 12.1 в книге, и вы увидите, как это сделать.

5
ответ дан Osurac 21 August 2018 в 11:53
поделиться
  • 1
    Не работает. warning (155): vhdl.g4: 1645: 24: правило SPACE содержит команду lexer с непризнанным постоянным значением; интерпретаторы lexer могут вызывать неправильную ошибку вывода (164): vhdl.g4: 26: 0: пользовательские каналы не поддерживаются в комбинированных грамматиках – betontalpfa 31 August 2015 в 08:47

Также можно использовать функцию «островные грамматики». См. Следующий раздел в книге ANTLR4:

Остроумные грамматики: обращение к разным форматам в одном файле

0
ответ дан snorbi 21 August 2018 в 11:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: