C#-Bibliothek zum Erstellen und Bearbeiten abstrakter Syntaxbäume beim Schreiben von Compilern.
Im Rahmen meines Oakley-Projekts zur Erstellung eines Compilers und des zugehörigen OakAsm-Projekts zur Erstellung eines Assemblers (Details folgen in Kürze) musste ich abstrakte Syntaxbäume in C# darstellen. Diese Bibliothek wurde erstellt, damit ich den Code zwischen diesen beiden Projekten teilen kann.
Erstellen Sie einen Basisknotentyp für Ihren abstrakten Syntaxbaum:
public abstract class Expression : Node < Expression >
{
}
Erstellen Sie spezifischere Knoten:
public sealed class ConstantNumber : Expression
{
public ConstantNumber ( int value )
{
Value = value ;
}
public int Value
{
get => Properties . GetOrThrow < int > ( nameof ( Value ) ) ;
init => Properties . Set ( nameof ( Value ) , value ) ;
}
}
public sealed class Addition : Expression
{
public Addition ( ConstantNumber x , ConstantNumber y )
{
Children . Add ( x ) ;
Children . Add ( y ) ;
}
}
Gehen Sie um den Baum herum:
var fifty = new ConstantNumber ( 50 ) ;
var sixty = new ConstantNumber ( 60 ) ;
var expression = new Addition ( fifty , sixty ) ;
var allNodes = expression . ThisAndDescendents ;
var fiftyAndParent = fifty . ThisAndAncestors ;
var fiftyAndSixty = fifty . ThisAndNextSiblings ;
var justSixty = sixty . PreviousSibling ;
var result = expression . Children . OfType < ConstantNumber > ( ) . Sum ( n => n . Value ) ;
Knoten mit Fehlern, Warnungen und Infomeldungen markieren:
sixty . AddError ( " Value must be less than 55. " ) ;
var expressionHasErrors = expression . HasErrors ; // true.
Verknüpfen Sie Knoten beim Parsen mit ihrer Position im Quellcode:
var source = new TextFile ( new FileInfo ( " MySource.code " ) ) ; // Contains "50 + 60".
expression . SourcePosition = source . CreatePosition ( 0 , 7 , 0 , 0 ) ; // startIndex, length, startLineIndex, startColumnIndex.
fifty . SourcePosition = source . CreatePosition ( 0 , 2 , 0 , 0 ) ;
sixty . SourcePosition = source . CreatePosition ( 5 , 2 , 0 , 5 ) ;
Ausgabefehler mit hervorgehobenen Quellinformationen:
var errors = MessageFormatter . FormatErrors ( expression ) ;
// MySource.code (1, 6): Error: Parent Value must be less than 55.
// 50 + 60
// --
Bearbeiten und kopieren Sie den Baum:
sixty . ReplaceWith ( new ConstantNumber ( 55 ) ) ;
var copy = expression . Copy ( ) ;
Die vollständige Dokumentation wird mit Version 1.0.x verfügbar sein.
dotnet add package MrKWatkins.Ast
Ich akzeptiere derzeit keine Pull-Anfragen. Dieses Projekt ist auf einige meiner anderen Projekte zugeschnitten und ich möchte sie zunächst in einen geeigneten Zustand bringen.
Fühlen Sie sich frei, Probleme mit Fehlern oder Vorschlägen zu melden, aber ich fürchte, ich gebe keine Garantie dafür, dass sie berücksichtigt werden!
MIT