import lexer_example
@with_lexer(foo_lexer)
grammar foo_grammar {
    @main_rule main_rule <- list+(or(scope | foreign_decl))
    scope <- Scope(simple_identifier "{" list*(scope) "}")
    identifier <- or(
        | ScopedId(identifier "." simple_identifier)
        | simple_identifier
    )
    simple_identifier <- SimpleId(@identifier)
    foreign_decl <- ForeignDecl("+" identifier "+" simple_identifier)

}

@abstract class FooNode : Node {
}

class ForeignDecl : FooNode {
    @parse_field dest_scope : Id
    @parse_field decl_id : SimpleId
}

@abstract class Id : FooNode {

    @abstract fun resolve (base_env : LexicalEnv): FooNode
}

class ScopedId : Id {
    @parse_field scope : Id
    @parse_field name : SimpleId

    fun resolve (base_env : LexicalEnv): FooNode =
    node.scope.resolve(base_env).children_env().get_first(node.name.symbol).node
}

class SimpleId : Id implements TokenNode {

    fun resolve (base_env : LexicalEnv): FooNode =
    base_env.get_first(node.symbol).node
}

class Scope : FooNode {
    @parse_field name : SimpleId
    @parse_field content : ASTList[Scope]
}
