Parser Module¶
This directory contains the drun v2 parser, refactored into domain-specific files for better organization and maintainability.
Architecture¶
The parser follows a domain-driven design where each file handles a specific aspect of the drun language:
Core Parser (parser.go) - 115 lines¶
The main orchestration layer containing:
Parserstruct definition- Constructor functions (
NewParser,NewParserWithSource) - Token advancement (
nextToken) - Main parsing loop (
ParseProgram)
This file delegates all actual parsing work to specialized domain files.
Domain-Specific Parser Files¶
Project-Level Parsing¶
parser_project.go - 807 lines¶
Handles project-level declarations and configuration:
- Version statements (
version: 2) - Project statements (
project "name") - Set statements (global variable declarations)
- Include statements (importing other files)
- Project parameters (
given $param as type) - Snippet definitions (
snippet "name") - Shell configuration (
shell:, platform-specific configs) - Lifecycle hooks (
before:,after:)
Task & Execution¶
parser_task.go - 432 lines¶
Parses task definitions and execution flow:
- Task statements (
task "name") - Task templates (
template task "name") - Task bodies (parameters, dependencies, statements)
- Dependency declarations (
depends on X, Y) - Task-from-template instantiation
parser_control.go - 603 lines¶
Control flow constructs:
- Conditional statements (
if,when,otherwise) - Loop statements (
for,for each) - Break/continue statements
- Control flow body parsing (statements within control blocks)
Data & Variables¶
parser_parameter.go - 311 lines¶
Parameter declarations and validation:
- Parameter statements (
requires $param as type) - Advanced constraints (range, pattern, validation)
- Type checking (string, number, boolean)
- Pattern macros (url, email, semver, etc.)
parser_variable.go - 281 lines¶
Variable operations:
- Variable declarations (
let $var = value) - Variable assignment (
set $var = value) - Variable transformation (
transform $var) - Variable capture from shell commands
parser_expression.go - 183 lines¶
Expression parsing:
- Binary expressions (arithmetic, logical)
- Literal expressions (strings, numbers, booleans)
- Identifier expressions (variables, references)
- Function calls (
function(args)) - Array literals (
[item1, item2])
Actions & Operations¶
parser_action.go - 105 lines¶
Action statements and task calls:
- Action statements (
info,step,success,warning,error) - Task call statements (
call task-name,call task "name" with iterations=100)
parser_shell.go - 175 lines¶
Shell command execution:
- Shell statements (
run "command",run "command" attached) - Multiline shell commands
- Command capture (
capture $var from command)
External Systems¶
parser_docker.go - 101 lines¶
Docker operations:
- Docker commands (
docker build,docker run, etc.) - Container management
parser_git.go - 256 lines¶
Git operations:
- Git commands (
git clone,git commit, etc.) - Branch and tag management
parser_http.go - 383 lines¶
HTTP operations:
- HTTP requests (
get,post,put,delete, etc.) - Download operations (
download from URL to path)
parser_network.go - 174 lines¶
Network operations:
- Health checks (
check health) - Port testing (
check if port X is open) - Ping operations
File Operations¶
parser_file.go - 295 lines¶
File system operations:
- File creation (
create file,create directory) - File manipulation (
copy,move,delete) - File I/O (
read,write,append) - File checks (
check if file exists)
Advanced Features¶
parser_detection.go - 212 lines¶
Smart detection operations:
- Tool detection (
detect docker,detect kubernetes) - Environment detection (
detect os,detect platform) - Context-aware parsing
parser_error.go - 111 lines¶
Error handling constructs:
- Try-catch statements (
try:,catch:) - Throw statements (
throw "error") - Error recovery
Utilities¶
parser_helpers.go - 461 lines¶
Helper functions and utilities:
- Token type checking (
isDockerToken,isGitToken, etc.) - Token expectation (
expectPeek,expectPeekSkipNewlines) - Error management (
addError,peekError) - Parsing utilities (
parseStringList,parseConditionExpression) - Pattern matching (
isPortCheckPattern,isDetectionContext)
Statistics¶
- Total lines: 5,466
- Domain files: 16
- Main parser: 115 lines (97.6% reduction from original 4,874 lines)
- Test coverage: 58/58 examples passing
Design Principles¶
- Single Responsibility: Each file handles one domain
- Same Package: All files in
parserpackage to avoid circular dependencies - Method Organization: Methods grouped by parsing domain, not by type
- Clear Naming: File names indicate their domain (
parser_<domain>.go) - Minimal Core:
parser.gocontains only orchestration logic
Usage¶
All parser files are part of the same parser package, so they can call each other's methods freely:
// In parser_task.go
func (p *Parser) parseTaskStatement() *ast.TaskStatement {
// Can call methods from parser_control.go
controlFlow := p.parseControlFlowStatement()
// Can call methods from parser_helpers.go
if p.isActionToken(p.curToken.Type) {
// ...
}
}
Future Enhancements¶
- Consider extracting common patterns into shared helpers
- Add inline documentation for complex parsing logic
- Create parser benchmarks for performance testing