-
Notifications
You must be signed in to change notification settings - Fork 0
Advanced
This page explores advanced topics in CDTk, including multi-target compilation, error handling, and writing custom validation rules. These features allow you to enhance the flexibility, robustness, and usability of your compilers.
Multi-target compilation allows you to generate output for multiple target languages or formats in a single compilation pass.
- You want the same source language to transpile into multiple output formats (e.g., C, Python, JavaScript).
- You want code generation and related tasks (such as linting or debugging comments) to happen simultaneously for multiple outputs.
In CDTk, you define a MapSet for each target language:
// Mapping for C
var cMapping = new MapSet
{
new Map("AssignmentNode", "int {variable} = {value};")
};
// Mapping for Python
var pythonMapping = new MapSet
{
new Map("AssignmentNode", "{variable} = {value}")
};
// Mapping for JavaScript
var jsMapping = new MapSet
{
new Map("AssignmentNode", "let {variable} = {value};")
};Use .WithTargets() to specify all the mappings for your targets:
var compiler = new Compiler()
.WithTokens(tokens)
.WithRules(rules)
.WithTargets(
("C", cMapping),
("Python", pythonMapping),
("JavaScript", jsMapping)
)
.Build();After compilation, you can access each target's generated output via result.Outputs:
var result = compiler.Compile(sourceCode);
if (result.Success)
{
Console.WriteLine("// C Output:");
Console.WriteLine(result.Outputs["C"]);
Console.WriteLine("// Python Output:");
Console.WriteLine(result.Outputs["Python"]);
Console.WriteLine("// JavaScript Output:");
Console.WriteLine(result.Outputs["JavaScript"]);
}
else
{
Console.WriteLine("Compilation failed.");
}Ensure that:
-
MapSetvariables are named clearly (e.g.,cMapping,jsMapping). - Target names specified in
.WithTargets()match user expectations (e.g.,"C","Python").
CDTk uses a robust diagnostics system to catch, report, and handle errors during all compilation stages.
-
Tokenization Errors:
- Reported during lexical analysis (e.g., when input text doesn’t match any token).
-
Parsing Errors:
- Occur when tokens violate your grammar rules.
-
Validation Errors:
- Semantic errors detected via custom validation logic.
You can report errors programmatically:
diagnostics.Add(
Stage.SyntaxAnalysis,
DiagnosticLevel.Error,
"Unexpected token found",
Token.Span
);- Info: Informational messages.
- Warning: Recoverable issues.
- Error: Prevents further compilation.
diagnostics.Add(Stage.SemanticAnalysis, DiagnosticLevel.Warning, "This is a warning.");
diagnostics.Add(Stage.LexicalAnalysis, DiagnosticLevel.Error, "Critical error encountered.");Use .Error() and .ErrorLevel() in grammar rules:
new Rule("Statement", "Assignment ';'")
.Error("Missing semicolon at the end of the statement.")
.ErrorLevel(DiagnosticLevel.Error);Custom validation rules are useful for enforcing semantic constraints that grammar alone cannot handle, such as:
- Variable scoping.
- Checking assigned values for type compatibility.
- Detecting reused or undeclared variables.
Use .Validate() to attach custom validation logic to a rule:
new Rule("Assignment", "@Identifier '=' Expression")
.Returns("AssignmentNode", "variable", "value")
.Validate((ctx, node, token) =>
{
var variable = node["variable"]?.ToString();
// Ensure variables are declared before use
if (!ctx.IsDeclared(variable))
{
ctx.Report(DiagnosticLevel.Error, $"Variable '{variable}' not declared.");
}
// Example validation: Ensure type compatibility between 'variable' and 'value'
if (node["value"].Type == "StringLiteral" && variable.StartsWith("_"))
{
ctx.Report(DiagnosticLevel.Warning, "Avoid assigning strings to reserved variables.");
}
});The validation context (ctx) provides access to:
- Scoping Information: Check declared variables, types, or rules.
- Reporting Diagnostics: Add warnings or errors.
ctx.IsDeclared(variable); // Checks if the variable is declared
ctx.Report(DiagnosticLevel.Error, "Custom error message");new Rule("Block", "'{' Statement* '}'")
.Returns("BlockNode", "statements")
.Validate((ctx, node, token) =>
{
// Example: Ensure no variable has multiple declarations in the same block.
var declaredVars = new HashSet<string>();
foreach (var stmt in node["statements"] as List<AstNode>)
{
if (stmt.Type == "VarDecl")
{
var variableName = stmt["name"]?.ToString();
if (!declaredVars.Add(variableName))
{
ctx.Report(DiagnosticLevel.Error, $"Variable '{variableName}' already declared in this block.");
}
}
}
});These advanced topics unlock the full potential of CDTk:
- Multi-target compilation simplifies producing multiple outputs from a single source.
- Error handling ensures robust feedback for users and developers.
- Custom validation adds semantic awareness to your compiler.
Explore these features to handle more complex and diverse requirements in your compilers.