No.46226
Пилю потихоньку свой генератор парсеров. Возникла маленькая проблема с обозначениями. Не знаю, какой синтаксис выбрать.
Вот смотри, Доброчан: я решил, что пусть каждая sequence у меня генерирует структуру, причем каждый capture будет полем в этой структуре. Например, вот такое parsing expression:
p:"ab" q:("de" r:"fg" "hi") "jkl"
распарсит входной текст вот в такую структуру:
AnonymousStruct1 {
p = "ab";
q = AnonymousStruct2 {
r = "fg";
};
}
Но в некоторых случаях я хочу распарсить данные не в анонимные структуры, а в свои собственные. Например, объявить где-нибудь:
struct MyText {
public string p;
public Object q;
}
а потом добавить в мое parsing expression:
p:"ab" q:("de" r:"fg" "hi") "jkl" -> MyText
и после парсинга получить MyText { p = "ab", q = AnonymousStruct }.
Но я ленивый и не хочу сначала объявлять структуру, потом еще прописывать ее в parsing expression. Я хочу написать один раз:
p:"ab" q:("de" r:"fg" "hi") "jkl" -> MyText
и чтоб генератор парсеров оттранслировал моё parsing expression в нечто такое:
#region Generated
struct MyText {
public string p;
public Object q;
}
class MyParser {
public Object Parse(InputReader input) {
... тут используется MyText ...
}
}
#endregion
Но тут возникает проблема: что если некоторые структуры я захочу определить сам? Например, файл "InnerPart.cs" содержит вот такое:
class InnerPart {
public string r;
}
а файл "parsing-expression.peg" - вот такое:
p:"ab" q:("de" r:"fg" "hi" -?> InnerPart) "jkl" -> MyText
И мой генератор сгенерирует два класса: MyParser и MyText, а InnerPart импортирует.
Это еще не все. У меня будут не только отдельные parsing expressions. Я смогу объединять их в правила:
Expr = p:"ab" "+" q:"cd";
Так вот, я хочу, чтобы имена правил также были именами типов. То есть, вот из этого примера генератор должен сгенерить нечто такое:
struct Expr {
public string p;
public string q;
}
class Parser {
public Object Parse(InputStream input) {
...
}
}
Но тут опять возникает проблема: что если мне не понравится структура, которую сгенерил генератор, что если мне захочется самому прописать ее? Как обозначить, что вот конкретно это правило не надо генерить, а надо импортировать?
ExprOne = p:"ab" "+" q:"cd";
// struct ExprOne сгенерируется генератором
???ExprTwo??? = r:"ab" "-" s:"cd";
// класс ExprTwo будет импортироваться извне
И я хочу сделать это обозначение единообразным и для имени правила, и для "xxx -> Struct".