Грамматика препроцессора Antlr4 интегрируется с грамматикой C - PullRequest
0 голосов
/ 22 февраля 2019

Я новичок в Antlr4.Я использую Antlr4 и antlr4 адаптер для анализа файлов C и создания дерева PSI.

Я знаю, что препроцессор C должен работать с компонентами #include и #define и передавать результат в лексер C иC parser.Но мне нужно разобрать #include и #define для C.g4 , чтобы мой плагин мог работать с файлом C без препроцессора.

Я посмотрел на эту ссылку и попробовал решение, но когда он встречает что-то отличное от оператора препроцессора, он не может решить.

образец кода C

#include <stdio.h>

int main()
{
  int i,j;
  for(i=1;i<=9;)
     {
      for(j=1;j<=9;j)
         {
           if(i>=j)
            {
              printf("%d*%d=%d    ",j,i,j*i);
            }
            j++;
         }
          printf("\n");
          i++;
     }
    return 0;
}

дерево результатов выглядит следующим образом

enter image description here

Вы можете видеть на изображениипосле блока include все элементы не являются деревом.

Я удалил строку #include в примере кода C и использовал оригинальную грамматику C.g4 , она может разрешить хороший PSIДерево, как это показано ниже:

enter image description here

Кто-нибудь поможет мне улучшить удар по грамматике?Так что моя грамматика может разрешить #include и #define как блок препроцессора в дереве PSI без использования препроцессоров.

Спасибо

Whitespace
:   [ \t]+
    -> channel(HIDDEN)
;
Newline
:   (   '\r' '\n'?
    |   '\n'
    )
    -> channel(HIDDEN)
;

BlockComment
:   '/*' .*? '*/'
;

LineComment
:   '//' ~[\r\n]*
;


IncludeBlock
 :   '#' Whitespace? 'include' ~[\r\n]*
 ;

DefineStart
:     '#' Whitespace? 'define'
;

DefineBlock
 :   DefineStart (~[\\\r\n] | '\\\\' '\r'? '\n' | '\\'. )*
 ;

MultiDefine
:   DefineStart MultiDefineBody
;

MultiDefineBody
:   [\\] [\r\n]+ MultiDefineBody
|   ~[\r\n]
;

preprocessorDeclaration
:   includeDeclaration
|   defineDeclaration
;

includeDeclaration
:   IncludeBlock
;

defineDeclaration
:   DefineBlock | MultiDefine
;

comment
:   BlockComment
|   LineComment
;

declaration
:   declarationSpecifiers initDeclaratorList ';'
|   declarationSpecifiers ';'
|   staticAssertDeclaration
|   preprocessorDeclaration
|   comment
;

1 Ответ

0 голосов
/ 22 февраля 2019

Я попробовал и решил свою проблему.

Трюк с новой строкой должен быть пропущен, как показано ниже в этой грамматике, он не должен использовать канал (HIDDEN).

Newline
:   (   '\r' '\n'?
|   '\n'
)
-> channel(HIDDEN)
;

следует изменить на

Newline
:   (   '\r' '\n'?
    |   '\n'
    )
    -> skip
;

хорошее дерево PSI выглядит следующим образом

хорошее дерево PSI с #include и # define

В любом случае, я не до конца понимаю разницу между каналом (HIDDEN) и пропуском.

...