import lexer_example
@with_lexer(foo_lexer)
grammar foo_grammar {
    @main_rule main_rule <- list+(decl)
    decl <- or(var_decl | fun_decl)
    var_decl <- VarDecl(VarKeyword("var") name "=" expr ";")
    fun_decl <- FunDecl("def" name ";")
    expr <- or(number | ref)
    number <- Number(@number)
    ref <- Ref(name)
    name <- Name(@identifier)

}

@abstract class FooNode : Node {
}

@abstract class Decl : FooNode {
    @abstract @parse_field name : Name
    @abstract @parse_field value : Expr
}

class FunDecl : Decl {
    @parse_field name : Name
    @parse_field @null_field value : Expr
}

class VarDecl : Decl {
    @parse_field var_kw : VarKeyword
    @parse_field name : Name
    @parse_field value : Expr
}

@abstract class Expr : FooNode {
}

class Number : Expr implements TokenNode {
}

class Ref : Expr {
    @parse_field name : Name
}

class Name : FooNode implements TokenNode {
}

class VarKeyword : FooNode implements TokenNode {
}
