Прагматичное упражнение по созданию кода для программиста - PullRequest
2 голосов
/ 10 августа 2010

Я читаю программист Pragmatic и выполняю следующее упражнение в мире .net (Глава 3 - Генераторы кода)

Упражнение

"Напишите генератор кода, который принимает входные данные в листинге 1 и генерирует выходные данные на двух языках по вашему выбору. Постарайтесь упростить добавление новых языков."

Листинг 1
# Добавить товар
# в список «под заказ»
M AddProduct
F id int
F name char [30]
F код заказа int
E

Как бы вы внедрили решение в T4 или что-то еще в мире .net (CodeDOM слишком сложен), чтобы мы могли генерировать код на c # и на одном другом языке .net (Visual Basic или IronRuby и т. Д.)

Ответы [ 3 ]

1 голос
/ 10 августа 2010

Я не думаю, что это должно быть упражнением в работе с существующими генераторами кода. На самом деле это намного больше. Я считаю, что цель состоит в том, чтобы создать свой собственный генератор кода, предметно-ориентированный язык и иметь дело с такими понятиями, как разбор и расширяемость / подключаемость. Возможно, я слишком много читаю в этом упражнении, но, возможно, речь идет скорее о развитии основных навыков / знаний разработчика, чем об обучении себя существующим инструментам.

1 голос
/ 12 августа 2010

Прислушиваясь к совету Бена Грисволда, я думаю, что это хорошая идея, чтобы реализовать его самостоятельно.И хотя совсем немного в реализации генератора кода в C #, я понял несколько вещей -
1. Нужен язык для работы с текстом, такой как Python и т. Д.
2. Нужно изучать Регулярные выражения

Я действительно собираюсьреализовать это в Ruby, но сейчас я реализовал это в C # как -

static void Main(string[] args)
{
    CodeGenerator gen = new CodeGenerator();
    gen.ReadFile("Input.txt");
}
public class CodeGenerator
{
    public void ReadFile(string filename)
    {
        StreamReader fs = new StreamReader(filename);
        string line;
        CSharpCode CG = new CSharpCode();

        while ((line = fs.ReadLine()) != null)
        {
            line = line.TrimEnd('\n');

            if (Regex.IsMatch(line, @"^\s*S"))
                CG.BlankLine();
            else if (Regex.IsMatch(line, @"^\#(.*)")) // match comments
                CG.Comment(line.TrimStart('#'));
            else if (Regex.IsMatch(line, @"^M\s*(.+)")) // start msg
                CG.StartMsg(line.Split(' ')[1]);
            else if (Regex.IsMatch(line, @"^E")) // end msg
                CG.EndMsg();
            else if (Regex.IsMatch(line, @"^F\s*(\w+)")) // simple type
                CG.SimpleType(Regex.Split(line, @"^F\s*(\w+)")[1], Regex.Split(line, @"^F\s*(\w+)")[2]);
            else
                Console.WriteLine("Invalid line " + line);
        }
    }
}

// Code Generator for C#
public class CSharpCode
{
    public void BlankLine() { Console.WriteLine(); }
    public void Comment(string comment) { Console.WriteLine("//" + comment); }
    public void StartMsg(string name) { Console.WriteLine("public struct " + name + "{"); }
    public void EndMsg() { Console.WriteLine("}"); }
    public void SimpleType(string name, string type)
    {
        if(type.Contains("char["))
            type = "string";

        Console.WriteLine(string.Format("\t{0} {1};", type.Trim(), name));
    }
}  
1 голос
/ 10 августа 2010

Я знаю, вы говорите, что CodeDOM слишком сложен, но я бы предложил использовать CodeDOM =). Вот краткий пример, с которого нужно начать: http://asp.dotnetheaven.com/howto/doc/listbuilder.aspx. Для вашего примера вы, вероятно, захотите добавить CodeMemberMethod к членам CodeTypeDeclaration - в MSDN есть несколько примеров.

Т4 может работать, но я не думаю, что он действительно идеально подходит для этой ситуации.

...