Sono riuscito a capirlo adattando l'esempio alla fine di Manuel Abadia's article.
Ecco la mia versione, che mi è capitato di utilizzare per convertire il codice analizzato in C#. Questi sono i passi:
- istanziare un ANTLRStringStream o sottoclasse con il vostro ingresso (che può essere un file o una stringa).
- Istanzia il tuo lexer generato, passando in quello stream di stringhe.
- Istanzia un flusso di token con il lexer.
- Istanzia il parser con quel flusso di token.
- Ottieni il valore di primo livello dal parser e trasformalo in
CommonTree
.
- attraversare l'albero:
Per ottenere il testo letterale di un nodo, utilizzare node.Text
. Per ottenere il nome del token di un nodo, utilizzare node.Token.Text
.
Nota che node.Token.Text
solo vi darà il nome effettivo del token se si tratta di un token immaginario con nessuna stringa corrispondente. Se si tratta di un vero token, quindi node.Token.Text
restituirà la stringa.
Ad esempio, se si ha il seguente nella tua grammatica:
tokens { PROGRAM, FUNCDEC }
EQUALS : '==';
ASSIGN : '=';
allora avrai "PROGRAM"
, "FUNCDEC"
, "=="
, e "="
dai corrispondenti accessi di node.Token.Text
.
Puoi vedere parte del mio esempio qui sotto, oppure puoi sfogliare lo full version.
public static string Convert(string input)
{
ANTLRStringStream sStream = new ANTLRStringStream(input);
MyGrammarLexer lexer = new MyGrammarLexer(sStream);
CommonTokenStream tStream = new CommonTokenStream(lexer);
MyGrammarParser parser = new MyGrammarParser (tStream);
MyGrammarParser.program_return parserResult = parser.program();
CommonTree ast = (CommonTree)parserResult.Tree;
Print(ast);
string output = header + body + footer;
return output;
}
public static void PrintChildren(CT ast)
{
PrintChildren(ast, " ", true);
}
public static void PrintChildren(CT ast, string delim, bool final)
{
if (ast.Children == null)
{
return;
}
int num = ast.Children.Count;
for (int i = 0; i < num; ++i)
{
CT d = (CT)(ast.Children[i]);
Print(d);
if (final || i < num - 1)
{
body += delim;
}
}
}
public static void Print(CommonTree ast)
{
switch (ast.Token.Text)
{
case "PROGRAM":
//body += header;
PrintChildren(ast);
//body += footer;
break;
case "GLOBALS":
body += "\r\n\r\n// GLOBALS\r\n";
PrintChildren(ast);
break;
case "GLOBAL":
body += "public static ";
PrintChildren(ast);
body += ";\r\n";
break;
....
}
}
qualsiasi codice di esempio di albero grammatica per C#? – Kiquenet