Hey ive a commencé à utiliser Antlr avec Java et je voulais savoir comment je pouvais stocker certaines valeurs directement dans un tableau 2d et retourner ce tableau? Je ne peux pas trouver de tutoriels à ce sujet, toute l'aide est appliquée.Antlr Array Help
Répondre
Disons que vous voulez analyser un fichier texte contenant des nombres séparés par des espaces. Vous souhaitez analyser cela dans un tableau 2d de int
où chaque ligne est une "ligne" dans votre tableau.
La grammaire ANTLR pour un « langage » pourrait ressembler à:
grammar Number;
parse
: line* EOF
;
line
: Number+ (LineBreak | EOF)
;
Number
: ('0'..'9')+
;
Space
: (' ' | '\t') {skip();}
;
LineBreak
: '\r'? '\n'
| '\r'
;
Maintenant, vous aimeriez avoir la règle parse
retourner un List
de List<Integer>
objets. Est-ce que par l'ajout d'un returns [List<List<Integer>> numbers]
après votre parse
règle qui peut être initialisé dans un @init{ ... }
bloc:
parse returns [List<List<Integer>> numbers]
@init {
$numbers = new ArrayList<List<Integer>>();
}
: line* EOF
;
Votre line
règle semble un peu la même chose, seulement il renvoie une 1 liste dimensions des nombres:
line returns [List<Integer> row]
@init {
$row = new ArrayList<Integer>();
}
: Number+ (LineBreak | EOF)
;
L'étape suivante consiste à remplir les List
avec les valeurs réelles qui sont en cours d'analyse.Cela peut se faire intégrer le code {$row.add(Integer.parseInt($Number.text));}
dans la boucle Number+
dans la règle line
:
line returns [List<Integer> row]
@init {
$row = new ArrayList<Integer>();
}
: (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF)
;
Et enfin, vous voulez ajouter les List
s renvoyés par votre règle line
être effectivement ajouté à votre 2D numbers
liste de votre règle parse
:
parse returns [List<List<Integer>> numbers]
@init {
$numbers = new ArrayList<List<Integer>>();
}
: (line {$numbers.add($line.row);})* EOF
;
Voici la grammaire finale:
grammar Number;
parse returns [List<List<Integer>> numbers]
@init {
$numbers = new ArrayList<List<Integer>>();
}
: (line {$numbers.add($line.row);})* EOF
;
line returns [List<Integer> row]
@init {
$row = new ArrayList<Integer>();
}
: (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF)
;
Number
: ('0'..'9')+
;
Space
: (' ' | '\t') {skip();}
;
LineBreak
: '\r'? '\n'
| '\r'
;
qui peut être testé avec la classe suivante:
import org.antlr.runtime.*;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
String source =
"1 2 \n" +
"3 4 5 6 7 \n" +
" 8 \n" +
"9 10 11 ";
ANTLRStringStream in = new ANTLRStringStream(source);
NumberLexer lexer = new NumberLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
NumberParser parser = new NumberParser(tokens);
List<List<Integer>> numbers = parser.parse();
System.out.println(numbers);
}
}
Générez un lexer et analyseur de la grammaire:
java -cp antlr-3.2.jar org.antlr.Tool Number.g
compiler tous les fichiers source .java
:
javac -cp antlr-3.2.jar *.java
et exécuter la classe principale:
// On *nix
java -cp .:antlr-3.2.jar Main
// or Windows
java -cp .;antlr-3.2.jar Main
qui produit la sortie suivante:
[[1, 2], [3, 4, 5, 6, 7], [8], [9, 10, 11]]
HTH
Voici quelques extraits d'une grammaire que j'ai faite qui analyse les noms des personnes et retourne un objet Name
. Devrait être suffisant pour vous montrer comment cela fonctionne. D'autres objets tels que les tableaux sont faits de la même manière.
Dans la grammaire:
grammar PersonNames;
fullname returns [Name name]
@init {
name = new Name();
}
: (directory_style[name] | standard[name] | title_without_fname[name] | family_style[name] | proper_initials[name]) EOF;
standard[Name name]
: (title[name] ' ')* fname[name] ' ' (mname[name] ' ')* (nickname[name] ' ')? lname[name] (sep honorifics[name])*;
fname[Name name] : (f=NAME | f=INITIAL) { name.set(Name.Part.FIRST, toNameCase($f.text)); };
dans votre code Java régulier
public static Name parseName(String str) throws RecognitionException {
System.err.println("parsing `" + str + "`");
CharStream stream = new ANTLRStringStream(str);
PersonNamesLexer lexer = new PersonNamesLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PersonNamesParser parser = new PersonNamesParser(tokens);
return parser.fullname();
}
Merci beaucoup ce qui est excellent, vous êtes – Jay
@Jay bienvenue. –