Ich experimentierte mit Rust macro_rules
und wollte ein Makro erstellen, das eine HTML-ähnliche Syntax parsen und das HTML einfach als String wiedergeben konnte. Die unten Makro wird die meisten der Weg dorthin:Überwindung der "lokalen Mehrdeutigkeit: mehrere Analyseoptionen:" in Rust Makros
macro_rules! html {
() => ("");
($text:tt) => {{
format!("{}", $text)
}};
(<$open:ident>[$($children:tt)*]</$close:ident>$($rest:tt)*) => {{
format!("<{}>{}</{}>{}",
stringify!($open),
html!($($children)*),
stringify!($close),
html!($($rest)*))
}};
}
und dann das Makro zu verwenden:
println!("{}",
html!(
<html>[
<head>[
<title>["Some Title"]</title>
]</head>
<body>[
<h1>["This is a header!"]</h1>
]</body>
]</html>
)
);
Allerdings würde ich wirklich die äußere Öffnung entfernen mögen und eckigen Klammern schließen. Ich versuche, das zu tun, wie folgt:
macro_rules! html_test {
() => ("");
($text:tt) => {{
format!("{}", $text)
}};
(<$open:ident>$($children:tt)*</$close:ident>$($rest:tt)*) => {{
format!("<{}>{}</{}>{}",
stringify!($open),
html!($($children)*),
stringify!($close),
html!($($rest)*))
}};
}
aber wenn ich dieses Makro zu verwenden:
println!("{}",
html_test!(
<html>
<head>
<title>"Some Title"</title>
</head>
<body>
<h1>"This is a header!"</h1>
</body>
</html>
)
);
ich die error: local ambiguity: multiple parsing options: built-in NTs tt ('children') or 1 other option.
ich die allgemeine Lösung kennen, um diesen Fehler zu Fügen Sie eine Syntax hinzu, um die Fälle zu unterscheiden (z. B. die eckigen Klammern hinzufügen). Gibt es in diesem speziellen Fall ein anderes Problem? Ich weiß, dass die Verwendung von prozeduralen Makros eine extreme Lösung wäre, aber ich würde es vorziehen, macro_rules
zu verwenden, wenn überhaupt möglich.
Ich realisiere mit einem Makro, um einfach eine Zeichenfolge mit HTML ist Overkill, aber es war nur für diese Fragen. Potenziell könnte man mit dem Makro viel interessantere Dinge tun, wie beispielsweise Funktionen aufrufen, um einen Baum aufzubauen, der die HTML-Struktur darstellt.
Danke für Ihre Antwort. Mir ist klar, dass die Verwendung dieses Makros zum einfachen Aufbau einer Zeichenkette ein bisschen lächerlich ist, aber das war nur der Frage zuliebe. Ich kann mir vorstellen, viel interessantere Dinge zu tun. Ich habe meine Frage bearbeitet, um dies zu erwähnen. Der größte Schmerzpunkt für mich sind die eckigen Klammern, die ich hinter die Notwendigkeit, String-Literale zu zitieren, schauen kann. Weißt du, ob das neue "Makro" -System das rosten würde? Würden Sie ein Prozedurmakro dafür empfehlen? – user7400966
@ user7400966: Rust's neues Makro-System existiert noch nicht, so kurz vor Zeitreisen, ich kann das nicht beantworten. Wie bei der Verwendung von prozeduralen Makros könnten Sie wahrscheinlich mit einigen Verrenkungen umgehen, die nur für Ableitungen unterstützt werden. –