5 votes

Analyse syntaxique avec des grammaires incomplètes

Existe-t-il des solutions communes pour utiliser les grammaires incomplètes ? Dans mon cas, je veux juste détecter les méthodes dans les fichiers Delphi (Pascal), c'est-à-dire procedures y functions . La première tentative suivante fonctionne

    methods
      : ( procedure | function | . )+
      ;

Mais s'agit-il d'une solution ? Existe-t-il de meilleures solutions ? Est-il possible d'arrêter l'analyse syntaxique par une action (par exemple, après la détection de implementation ). Est-il judicieux d'utiliser un préprocesseur ? Et si oui, comment ?

4voto

Bart Kiers Points 79069

Si vous ne cherchez que des noms, alors quelque chose d'aussi simple que ceci :

grammar PascalFuncProc;

parse
  :  (Procedure | Function)* EOF
  ;

Procedure
  :  'procedure' Spaces Identifier
  ;

Function
  :  'function' Spaces Identifier
  ;

Ignore
  :  (StrLiteral | Comment | .) {skip();}
  ;

fragment Spaces     : (' ' | '\t' | '\r' | '\n')+;
fragment Identifier : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*;
fragment StrLiteral : '\'' ~'\''* '\'';
fragment Comment    : '{' ~'}'* '}';

fera l'affaire. Notez que je ne suis pas très familier avec Delhpi/Pascal, donc je me trompe sûrement. StrLiteral et/ou Comment mais cela sera facilement corrigé.

Le lexateur généré à partir de la grammaire ci-dessus ne produira que deux types de jetons ( Procedure et Function ), le reste de l'entrée (chaînes de caractères, commentaires ou, si rien n'est trouvé, un seul caractère : l'option . ) est immédiatement éliminé du lexateur (la balise skip() ).

Pour une entrée comme celle-ci :

some valid source
{ 
  function NotAFunction ...
}

procedure Proc
Begin
  ...
End;

procedure Func
Begin
  s = 'function NotAFunction!!!'
End;

l'arbre d'analyse suivant est créé :

enter image description here

4voto

Ira Baxter Points 48153

Ce que vous demandez s'appelle grammaires insulaires . L'idée est de définir un analyseur pour la partie du langage qui vous intéresse (l'"île") avec toute la tokenisation classique nécessaire pour cette partie, et de définir un analyseur extrêmement négligé pour ignorer le reste (l'"océan" dans lequel l'île est immergée). Une astuce courante pour y parvenir consiste à définir des lexeurs aussi peu rigoureux, qui récupèrent de grandes quantités de choses (pour passer du HTML au code intégré, vous pouvez essayer de passer tout ce qui ne ressemble pas à une balise script dans le lexateur, par exemple).

Le site de l'ANTLR examine certaines questions connexes mais indique notamment que des exemples sont fournis avec ANTLR. Je n'ai aucune expérience avec ANTLR et je ne sais donc pas si cette information spécifique est utile.

Ayant construit de nombreux outils qui utilisent des analyseurs pour analyser/transformer du code (voir ma bio), je suis un peu pessimiste quant à l'utilité générale des grammaires insulaires. A moins que votre but ne soit de faire quelque chose d'assez trivial avec l'île analysée, vous aurez besoin de collecter la signification de tous les identifiants qu'elle utilise directement ou indirectement... et la plupart d'entre eux sont malheureusement pour vous définis dans l'océan. Donc, IMHO, vous devez analyser l'océan aussi pour dépasser les tâches triviales. Vous aurez aussi d'autres problèmes, en vous assurant que vous sautez vraiment les trucs de l'île ; cela signifie que votre lexateur de l'océan doit connaître les espaces blancs, les commentaires, et toute la syntaxe pointilleuse des chaînes de caractères (c'est plus difficile qu'il n'y paraît avec les langages modernes) afin qu'ils soient correctement ignorés. YMMV.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X