2017-06-06 5 views
1

Je fais des exercices pratiques avec antlr4 pour analyser un fichier et semble être bloqué avec un problème qui m'a empêché de rester éveillé pendant quelques heures maintenant. Voici la grammaire simple que j'ai définie dans le fichier ESQLGrammar.g4 qui est placé dans mes projets src/main/antlr4.impossible d'analyser la grammaire simple en utilisant antlr4

grammar ESQLGrammar; 

esqlCode: 
    declBrokerSchema? esqlContents; 

declBrokerSchema 
    : BROKER SCHEMA schemaName (PATH schemaPathList ';')?; 
schemaName 
    : IDENTIFIER; 
schemaPathList 
    : IDENTIFIER (',' IDENTIFIER)*; 

esqlContents 
    : (declareVariable)*?; 

declareVariable 
    : DECLARE variableNames esqlDataType ';'; 
variableNames 
    : variableName (',' variableName)*; 
variableName 
    : IDENTIFIER; 
esqlDataType  
    : (BLOB|CHARACTER|BOOLEAN|NAMESPACE); 

WS    : [ \r\t\n]+ -> skip ; 
IDENTIFIER  : [a-zA-Z_][a-zA-Z0-9_.]*; 

BROKER : 'BROKER'; 
SCHEMA : 'SCHEMA'; 
PATH : 'PATH'; 
DECLARE : 'DECLARE'; 
BLOB  : 'BLOB'; 
CHARACTER : 'CHARACTER'; 
BOOLEAN : 'BOOLEAN'; 
NAMESPACE : 'NAMESPACE'; 

Mon entrée est un fichier

BROKER SCHEMA nameOfSchema PATH pathVal1,pathVal2; 
DECLARE iSharedVar CHARACTER; 

Cependant, quand je change les lignes de grammaire ci-dessous pour utiliser des mots clés fixes avec des espaces supplémentaires dans les

declBrokerSchema 
    : 'BROKER SCHEMA ' schemaName ('PATH ' schemaPathList ';')?; 
// Notice the keywords in ' ' with extra space at end. 
declareVariable 
    : 'DECLARE ' variableNames esqlDataType ';'; 

il semble analyser les lignes et renvoie l'erreur fournie ci-dessous:

line 2:19 mismatched input 'CHARACTER' expecting {'BLOB', 'CHARACTER', 'BOOLEAN', 'NAMESPACE'} 

DeclBrokerSchema(schemaName=nameOfSchema, schemaPathList=pathVal1,pathVal2) 
[DeclareVariable(varibleNames=iSharedVar, dataType=CHARACTER, defultValue=null, modifier=null, isConstant=false, aliasType=null, initialValueExpression=null)] 

qui semble le reconnaître mais avec une erreur. Donc besoin de votre avis d'expert sur ces:

  • Je ne peux trouver aucune des règles qui auraient pu appariés « caractère » pendant la phase de lexer .. alors pourquoi faut-il lancer une erreur?
  • En outre, pourquoi est-ce que cela m'oblige à utiliser les jetons dans '' aussi avec un espace supplémentaire? Si je supprime l'espace, il ne parvient pas à l'analyser ..

Suis-je manquer quelque chose ici .. pls aider ..!

Répondre

1

Votre grammaire d'origine est correcte, à l'exception d'une erreur faible mais significative dans vos règles lexer. En raison de cette erreur, la quasi-totalité de votre entrée est en cours tokenizés par le lexer comme IDENTIFIER:

[@0,0:5='BROKER',<IDENTIFIER>,1:0] 
[@1,7:12='SCHEMA',<IDENTIFIER>,1:7] 
[@2,14:25='nameOfSchema',<IDENTIFIER>,1:14] 
[@3,27:30='PATH',<IDENTIFIER>,1:27] 
[@4,32:39='pathVal1',<IDENTIFIER>,1:32] 
[@5,40:40=',',<','>,1:40] 
[@6,41:48='pathVal2',<IDENTIFIER>,1:41] 
[@7,49:49=';',<';'>,1:49] 
[@8,52:58='DECLARE',<IDENTIFIER>,2:0] 
[@9,60:69='iSharedVar',<IDENTIFIER>,2:8] 
[@10,71:79='CHARACTER',<IDENTIFIER>,2:19] 
[@11,80:80=';',<';'>,2:28] 
[@12,83:82='<EOF>',<EOF>,3:0] 

Donc, nous allons corriger cela en déplaçant la règle de lexer pour IDENTIFIER au fond de telle sorte que cette règle ne match avant tout le reste:

etc... 
BLOB  : 'BLOB'; 
CHARACTER : 'CHARACTER'; 
BOOLEAN : 'BOOLEAN'; 
NAMESPACE : 'NAMESPACE'; 
IDENTIFIER  : [a-zA-Z_][a-zA-Z0-9._]*; 

maintenant, si vous exécutez le lexer tokenizes la façon dont vous vous attendez:

[@0,0:5='BROKER',<'BROKER'>,1:0] 
[@1,7:12='SCHEMA',<'SCHEMA'>,1:7] 
[@2,14:25='nameOfSchema',<IDENTIFIER>,1:14] 
[@3,27:30='PATH',<'PATH'>,1:27] 
[@4,32:39='pathVal1',<IDENTIFIER>,1:32] 
[@5,40:40=',',<','>,1:40] 
[@6,41:48='pathVal2',<IDENTIFIER>,1:41] 
[@7,49:49=';',<';'>,1:49] 
[@8,52:58='DECLARE',<'DECLARE'>,2:0] 
[@9,60:69='iSharedVar',<IDENTIFIER>,2:8] 
[@10,71:79='CHARACTER',<'CHARACTER'>,2:19] 
[@11,80:80=';',<';'>,2:28] 
[@12,83:82='<EOF>',<EOF>,3:0] 

maintenant, cela fonctionne. L'ordre des règles lexer est important. Rappelez-vous que les règles sont évaluées de haut en bas. ;)

+0

Marvelous ..! C'était sur place ..! Merci un million @JLH pour celui-ci ..! Je comprends maintenant la commande qui est mentionnée dans la documentation d'antlr mais peut-être n'ai pas réalisé que cela fait une grande différence ..! Accepté et mis à jour ..! Merci encore .. – Qadeer

+0

par curiosité, comment puis-je obtenir les jetons comme celui que vous avez imprimé? Est-ce un paramètre de débogage ou vous utilisez des outils autour d'elle? – Qadeer

+0

J'ai lancé l'application Java appelée TestRig en mode -tokens, merci. L'utilisation de celui-ci est bien décrite dans le livre de Terence Parr sur Antlr. – TomServo