Tôi đã cố gắng tìm ra điều này bằng cách điều chỉnh ví dụ ở cuối Manuel Abadia's article.
Đây là phiên bản của tôi, mà tôi đang sử dụng để chuyển đổi mã được phân tách thành C#. Đây là những bước sau:
- Khởi tạo một ANTLRStringStream hoặc lớp con với đầu vào của bạn (nó có thể là một tập tin hoặc chuỗi).
- Khởi tạo từ khóa được tạo của bạn, chuyển qua luồng chuỗi đó.
- Tạo luồng mã thông báo bằng từ khóa.
- Làm nhanh trình phân tích cú pháp của bạn bằng luồng mã thông báo đó.
- Lấy giá trị cấp cao nhất từ trình phân tích cú pháp của bạn và biến nó thành một
CommonTree
.
- Traverse cây:
Để có được văn bản đen của một nút, sử dụng node.Text
. Để lấy tên mã thông báo của một nút, hãy sử dụng node.Token.Text
.
Lưu ý rằng node.Token.Text
sẽ chỉ cung cấp cho bạn tên thực của mã thông báo nếu đó là mã thông báo ảo không có chuỗi tương ứng. Nếu đó là mã thông báo thực, thì node.Token.Text
sẽ trả về chuỗi của nó.
Ví dụ, nếu bạn có điều sau đây trong ngữ pháp của bạn:
tokens { PROGRAM, FUNCDEC }
EQUALS : '==';
ASSIGN : '=';
Sau đó, bạn sẽ nhận được "PROGRAM"
, "FUNCDEC"
, "=="
, và "="
từ truy cập tương ứng của node.Token.Text
.
Bạn có thể xem một phần ví dụ của tôi bên dưới hoặc bạn có thể duyệt qua 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;
....
}
}
bất kỳ mẫu mã của Tree Grammar for C#? – Kiquenet