mirror of
https://github.com/AdaCore/langkit.git
synced 2026-02-12 12:28:12 -08:00
It was not allowed so far because of an oversight in the recent revamp of the module system.
524 lines
15 KiB
Plaintext
524 lines
15 KiB
Plaintext
from nodes import *
|
|
import tokens
|
|
|
|
@with_lexer(tokens.lkt_lexer)
|
|
@with_unparsers
|
|
grammar lkt_grammar {
|
|
@main_rule
|
|
main_rule <- LangkitRoot(/ module_doc imports decls @Termination)
|
|
id <- Id(@Identifier)
|
|
ref_id <- RefId(@Identifier)
|
|
type_ref_id <- ref_id |> when(Id.is_type_name)
|
|
module_id <- ModuleId(@Identifier) |> when(Id.is_not_type_name)
|
|
def_id <- DefId(@Identifier)
|
|
doc <- ?string_lit
|
|
module_doc <- ?ModuleDocStringLit(
|
|
list+(ModuleDocStringLine(@ModuleDocStringLine))
|
|
)
|
|
imported_names <- list+(
|
|
ImportedName(
|
|
ImportedId(@Identifier)
|
|
/
|
|
?pick(@Identifier("as") / def_id)
|
|
),
|
|
","
|
|
)
|
|
import_clause <- or(
|
|
| Import("import" / imported_names)
|
|
| ImportFrom("from" module_id "import" imported_names)
|
|
| ImportAllFrom("from" / module_id "import" "*")
|
|
)
|
|
imports <- list*(import_clause)
|
|
lexer_decl <- LexerDecl(
|
|
"lexer"
|
|
/
|
|
def_id
|
|
"{"
|
|
list*(or(lexer_case_rule | decl)).dont_skip("}")
|
|
"}"
|
|
)
|
|
grammar_decl <- GrammarDecl("grammar" / def_id "{" decls "}")
|
|
grammar_rule <- GrammarRuleDecl(def_id "<-" grammar_expr)
|
|
lexer_case_rule <- LexerCaseRule(
|
|
"match" / grammar_primary "{" list*(lexer_case_alt).dont_skip("}") "}"
|
|
)
|
|
lexer_case_alt <- or(
|
|
| LexerCaseRuleCondAlt(
|
|
"if"
|
|
/
|
|
@Identifier("previous_token")
|
|
"is"
|
|
list+(ref_id, "|")
|
|
"then"
|
|
lexer_case_send
|
|
)
|
|
| LexerCaseRuleDefaultAlt("else" / lexer_case_send)
|
|
| skip(ErrorLexerCaseRuleAlt)
|
|
)
|
|
lexer_case_send <- LexerCaseRuleSend(
|
|
@Identifier("send") "(" ref_id "," num_lit ")"
|
|
)
|
|
grammar_primary <- or(
|
|
| grammar_pick
|
|
| grammar_list_expr
|
|
| token_literal
|
|
| token_no_case_literal
|
|
| token_pattern
|
|
| grammar_cut
|
|
| grammar_skip
|
|
| grammar_null
|
|
| grammar_token
|
|
| grammar_stopcut
|
|
| parse_node_expr
|
|
| grammar_opt
|
|
| grammar_opt_error
|
|
| grammar_or_expr
|
|
| grammar_rule_ref
|
|
| grammar_discard_expr
|
|
| skip(ErrorGrammarExpr)
|
|
)
|
|
grammar_expr <- or(
|
|
| GrammarDontSkip(
|
|
grammar_expr "." @Identifier("dont_skip") "(" grammar_expr ")"
|
|
)
|
|
| GrammarPredicate(
|
|
grammar_expr "|>" "when" "(" basic_name ")"
|
|
)
|
|
| grammar_primary
|
|
)
|
|
grammar_pick <- GrammarPick(
|
|
@Identifier("pick") "(" list+(grammar_expr).dont_skip(")") ")"
|
|
)
|
|
grammar_implicit_pick <- GrammarImplicitPick(list+(grammar_expr))
|
|
grammar_opt <- or(
|
|
| GrammarOptGroup("?" "(" / list*(grammar_expr).dont_skip(")") ")")
|
|
| GrammarOpt("?" / grammar_expr)
|
|
)
|
|
grammar_opt_error <- or(
|
|
| GrammarOptErrorGroup(
|
|
"!" "(" / list*(grammar_expr).dont_skip(")") ")"
|
|
)
|
|
| GrammarOptError("!" / grammar_expr)
|
|
)
|
|
grammar_cut <- GrammarCut("/")
|
|
grammar_stopcut <- GrammarStopCut(
|
|
@Identifier("stop_cut") "(" grammar_expr ")"
|
|
)
|
|
grammar_or_expr <- GrammarOrExpr(
|
|
"or"
|
|
"("
|
|
list+(
|
|
list+(grammar_expr).dont_skip("|"), "|", allow_leading
|
|
).dont_skip(")")
|
|
")"
|
|
)
|
|
grammar_discard_expr <- GrammarDiscard("discard" "(" grammar_expr ")")
|
|
token_literal <- TokenLit(@String)
|
|
token_no_case_literal <- TokenNoCaseLit(
|
|
@Identifier("no_case") "(" token_literal ")"
|
|
)
|
|
token_pattern <- or(
|
|
| TokenPatternConcat(token_pattern "&" token_pattern_literal)
|
|
| token_pattern_literal
|
|
)
|
|
token_pattern_literal <- TokenPatternLit(@PString)
|
|
parse_node_expr <- ParseNodeExpr(
|
|
type_ref
|
|
"("
|
|
/
|
|
list*(grammar_expr).dont_skip(")")
|
|
")"
|
|
)
|
|
grammar_rule_ref <- GrammarRuleRef(ref_id)
|
|
grammar_list_expr <- GrammarList(
|
|
# Match either "list" (type inference will determine the list type) or
|
|
# a specific list type.
|
|
or(DefaultListTypeRef(@Identifier("list")) | type_ref)
|
|
|
|
or(ListKind.One("+") | ListKind.Zero("*"))
|
|
"("
|
|
|
|
# Main list expr
|
|
or(grammar_implicit_pick | grammar_expr).dont_skip(")").dont_skip(",")
|
|
|
|
# Separator
|
|
?pick("," grammar_list_sep)
|
|
")"
|
|
)
|
|
grammar_list_sep <- GrammarListSep(grammar_expr ?pick("," id))
|
|
grammar_skip <- GrammarSkip(@Identifier("skip") "(" type_ref ")")
|
|
grammar_null <- GrammarNull("null" ?pick("(" type_ref ")"))
|
|
grammar_token <- TokenRef("@" ref_id ?pick("(" token_literal ")"))
|
|
type_decl <- or(
|
|
| StructDecl(
|
|
"struct"
|
|
/
|
|
def_id
|
|
?pick("implements" / type_list)
|
|
"{"
|
|
decl_block.dont_skip("}")
|
|
"}"
|
|
)
|
|
| EnumClassDecl(
|
|
"enum"
|
|
"class"
|
|
/
|
|
def_id
|
|
?pick(":" type_ref)
|
|
?pick("implements" type_list)
|
|
"{"
|
|
list*(
|
|
EnumClassCase(
|
|
"case"
|
|
list+(EnumClassAltDecl(def_id null(ASTList[TypeRef])), ",")
|
|
)
|
|
)
|
|
decl_block.dont_skip("}")
|
|
"}"
|
|
)
|
|
| ClassDecl(
|
|
"class"
|
|
/
|
|
def_id
|
|
?pick(":" / type_ref)
|
|
?pick("implements" / type_list)
|
|
"{"
|
|
decl_block.dont_skip("}")
|
|
"}"
|
|
)
|
|
| EnumTypeDecl(
|
|
"enum"
|
|
/
|
|
def_id
|
|
?pick("implements" type_list)
|
|
"{"
|
|
"case"
|
|
list+(enum_lit_decl, ",")
|
|
decl_block.dont_skip("}")
|
|
"}"
|
|
)
|
|
| TraitDecl(
|
|
"trait"
|
|
/
|
|
def_id
|
|
null(ASTList[TypeRef])
|
|
"{"
|
|
decl_block.dont_skip("}")
|
|
"}"
|
|
)
|
|
)
|
|
generic_decl <- GenericDecl(
|
|
"generic"
|
|
/
|
|
"["
|
|
GenericParamDeclList+(generic_param_type, ",")
|
|
"]"
|
|
bare_decl
|
|
)
|
|
generic_param_type <- FullDecl(
|
|
doc
|
|
list*(decl_annotation)
|
|
GenericParamTypeDecl(
|
|
ClassQualifier("class") def_id null(ASTList[TypeRef])
|
|
)
|
|
)
|
|
enum_lit_decl <- EnumLitDecl(def_id)
|
|
fun_decl <- FunDecl(
|
|
"fun"
|
|
/
|
|
def_id
|
|
"("
|
|
fun_param_list
|
|
")"
|
|
":"
|
|
type_ref
|
|
?pick("implements" type_member_ref)
|
|
?pick("=" expr)
|
|
)
|
|
lambda_param_decl <- LambdaParamDecl(
|
|
def_id ?pick(":" type_ref) ?pick("=" expr)
|
|
)
|
|
fun_param_decl <- FunParamDecl(
|
|
list*(decl_annotation) def_id ":" type_ref ?pick("=" expr)
|
|
)
|
|
fun_param_list <- list*(fun_param_decl, ",")
|
|
lambda_param_list <- list*(lambda_param_decl, ",")
|
|
field_decl <- FieldDecl(
|
|
def_id
|
|
":"
|
|
type_ref
|
|
?pick("implements" type_member_ref)
|
|
?pick("=" expr)
|
|
)
|
|
lexer_family_decl <- LexerFamilyDecl(
|
|
@Identifier("family") / def_id "{" list*(decl).dont_skip("}") "}"
|
|
)
|
|
bare_decl <- or(
|
|
| generic_decl
|
|
| type_decl
|
|
| fun_decl
|
|
| lexer_decl
|
|
| grammar_decl
|
|
| field_decl
|
|
| val_decl
|
|
| env_spec_decl
|
|
| lexer_family_decl
|
|
| grammar_rule
|
|
| dynvar_decl
|
|
| skip(ErrorDecl)
|
|
)
|
|
decl <- FullDecl(doc list*(decl_annotation) bare_decl)
|
|
type_member_ref <- DotExpr(type_ref_id null(NullCondQualifier)"." / ref_id)
|
|
type_expr <- or(
|
|
| DotExpr(module_id null(NullCondQualifier)"." / type_ref_id)
|
|
| DotExpr(type_expr null(NullCondQualifier)"." / type_ref_id)
|
|
| type_ref_id
|
|
)
|
|
type_ref <- or(
|
|
| GenericTypeRef(type_expr "[" type_list "]")
|
|
| SimpleTypeRef(type_expr)
|
|
| FunctionTypeRef("(" list*(type_ref, ",") ")" "->" type_ref)
|
|
)
|
|
type_list <- list+(type_ref, ",")
|
|
decls <- list*(decl).dont_skip("}")
|
|
decl_block <- DeclBlock*(decl)
|
|
val_decl <- ValDecl("val" / def_id ?pick(":" type_ref) "=" expr)
|
|
dynvar_decl <- DynVarDecl("dynvar" def_id ":" type_ref)
|
|
var_bind <- VarBind("bind" / ref_id "=" expr)
|
|
env_spec_action <- CallExpr(RefId(@Identifier) "(" args ")")
|
|
env_spec_decl <- EnvSpecDecl(
|
|
DefId(@Identifier("env_spec")) "{" list*(env_spec_action) "}"
|
|
)
|
|
block <- BlockExpr(
|
|
"{"
|
|
/
|
|
list+(
|
|
or(
|
|
| BlockExprClause(or(var_bind | decl) ";")
|
|
| expr
|
|
| skip(ErrorDecl)
|
|
)
|
|
).dont_skip("}")
|
|
"}"
|
|
)
|
|
pattern <- or(OrPattern(neg_pattern "|" pattern) | neg_pattern)
|
|
neg_pattern <- or(
|
|
| NotPattern("not" neg_pattern)
|
|
| complex_pattern
|
|
)
|
|
pattern_binding <- BindingValDecl(def_id)
|
|
complex_pattern <- or(
|
|
| ComplexPattern(
|
|
null(BindingValDecl)
|
|
value_pattern
|
|
?pick("(" / list+(pattern_arg, ",") ")")
|
|
?pick("when" expr)
|
|
)
|
|
| ComplexPattern(
|
|
?pick(pattern_binding "@")
|
|
value_pattern
|
|
?pick("(" / list+(pattern_arg, ",") ")")
|
|
?pick("when" expr)
|
|
)
|
|
| ComplexPattern(
|
|
?pick(pattern_binding "@")
|
|
AnyTypePattern("*")
|
|
"(" / list+(pattern_arg, ",") ")"
|
|
?pick("when" expr)
|
|
)
|
|
| RenamingComplexPattern(
|
|
pattern_binding
|
|
null(Pattern)
|
|
null(ASTList[PatternDetail])
|
|
?pick("when" expr)
|
|
)
|
|
)
|
|
value_pattern <- or(
|
|
| TypePattern(type_ref)
|
|
| NullPattern("null")
|
|
| regex_pattern
|
|
| bool_pattern
|
|
| integer_pattern
|
|
| list_pattern
|
|
| ParenPattern("(" pattern ")")
|
|
)
|
|
regex_pattern <- RegexPattern(@String)
|
|
|
|
# Boolean patterns use hard-coded "true" & "false" identifiers, even though
|
|
# booleans literals are not built-in in Langkit but just a regular enum.
|
|
bool_pattern <- or(
|
|
| BoolPattern.True(@Identifier("true"))
|
|
| BoolPattern.False(@Identifier("false"))
|
|
)
|
|
|
|
ellipsis_pattern <- EllipsisPattern(?pick(id "@") "...")
|
|
integer_pattern <- IntegerPattern(@Number)
|
|
list_pattern <- ListPattern(
|
|
"[" list+(or(ellipsis_pattern | neg_pattern), ",") "]"
|
|
)
|
|
pattern_arg <- or(
|
|
| FieldPatternDetail(id ":" / pattern)
|
|
| PropertyPatternDetail(
|
|
CallExpr(ref_id "(" / args ")") ":" / pattern
|
|
)
|
|
)
|
|
expr <- or(
|
|
| BinOp(stream_concat Op.StreamConcat(":::") expr)
|
|
| stream_concat
|
|
)
|
|
stream_concat <- or(
|
|
| BinOp(logic Op.StreamCons("::") stream_concat)
|
|
| logic
|
|
)
|
|
logic <- or(
|
|
| BinOp(
|
|
logic
|
|
or(
|
|
| Op.OrInt("or" "?")
|
|
| Op.Or("or")
|
|
| Op.And("and")
|
|
| Op.LogicAnd("%" "and")
|
|
| Op.LogicOr("%" "or")
|
|
)
|
|
rel
|
|
)
|
|
| rel
|
|
)
|
|
rel <- or(NotExpr("not" eq) | eq)
|
|
eq <- or(
|
|
| BinOp(
|
|
eq
|
|
or(
|
|
| Op.Lte("<=")
|
|
| Op.Lt("<")
|
|
| Op.Gte(">=")
|
|
| Op.Gt(">")
|
|
| Op.Eq("==")
|
|
| Op.Ne("!=")
|
|
)
|
|
arith_1
|
|
)
|
|
| arith_1
|
|
)
|
|
arith_1 <- or(
|
|
| BinOp(arith_1 or(Op.Plus("+") | Op.Minus("-") | Op.Amp("&")) arith_2)
|
|
| arith_2
|
|
)
|
|
arith_2 <- or(
|
|
| BinOp(arith_2 or(Op.Mult("*") | Op.Div("/")) arith_3)
|
|
| arith_3
|
|
)
|
|
arith_3 <- or(
|
|
| UnOp(or(Op.Plus("+") | Op.Minus("-")) isa_or_primary)
|
|
| isa_or_primary
|
|
)
|
|
isa_or_primary <- or(
|
|
| Isa(primary "is" / pattern)
|
|
| AnyOf(primary "in" / AnyOfList+(primary, "|"))
|
|
| LogicUnify(isa_or_primary "<->" / primary)
|
|
| LogicPropagate(isa_or_primary "<-" logic_propagate_call)
|
|
| LogicAssign(isa_or_primary "<-" / primary)
|
|
| primary
|
|
)
|
|
logic_propagate_call <- LogicPropagateCall(callable_ref "%" "(" args ")")
|
|
primary <- or(| lambda_expr | if_expr | raise_expr | try_expr | basic_expr)
|
|
match_expr <- MatchExpr(
|
|
"match"
|
|
/
|
|
expr
|
|
"{"
|
|
list+(or(
|
|
| PatternMatchBranch("case" pattern "=>" / expr)
|
|
| MatchBranch(
|
|
"case" MatchValDecl(def_id ?pick(":" / type_ref)) "=>" / expr
|
|
)
|
|
))
|
|
"}"
|
|
)
|
|
num_lit <- NumLit(@Number)
|
|
big_num_lit <- BigNumLit(@BigNumber)
|
|
string_lit <- or(
|
|
| SingleLineStringLit(@String)
|
|
| PatternSingleLineStringLit(@PString)
|
|
| block_string_lit
|
|
)
|
|
block_string_lit <- BlockStringLit(
|
|
list+(BlockStringLine(@BlockStringLine))
|
|
)
|
|
char_lit <- CharLit(@Char)
|
|
if_expr <- IfExpr(
|
|
"if"
|
|
/
|
|
expr
|
|
"then"
|
|
expr
|
|
list*(ElsifBranch("elif" / expr "then" expr))
|
|
"else"
|
|
expr
|
|
)
|
|
raise_expr <- RaiseExpr("raise" / ?pick("[" / type_ref "]") expr)
|
|
try_expr <- TryExpr("try" / expr ?pick("else" / expr))
|
|
array_literal <- ArrayLiteral(
|
|
"[" / list*(expr, ",") "]" ?pick(":" / type_ref)
|
|
)
|
|
callable_ref <- or(
|
|
DotExpr(callable_ref null(NullCondQualifier) "." ref_id) | ref_id
|
|
)
|
|
null_cond_qual <- NullCondQualifier("?")
|
|
basic_expr <- or(
|
|
| CallExpr(basic_expr "(" / args ")")
|
|
| GenericInstantiation(basic_expr "[" type_list "]")
|
|
| SubscriptExpr(basic_expr null_cond_qual "[" / expr "]")
|
|
| ErrorOnNull(basic_expr "!")
|
|
| KeepExpr(
|
|
basic_expr null_cond_qual "." @Identifier("keep") "[" type_ref "]"
|
|
)
|
|
| CastExpr(
|
|
basic_expr
|
|
null_cond_qual
|
|
"."
|
|
@Identifier("as")
|
|
/
|
|
ExcludesNull("!")
|
|
"["
|
|
type_ref
|
|
"]"
|
|
)
|
|
| LogicPredicate(basic_expr "%" "(" / args ")")
|
|
| DotExpr(basic_expr null_cond_qual "." / ref_id)
|
|
| LogicExpr("%" CallExpr(ref_id "(" / args ")"))
|
|
| LogicExpr("%" / ref_id)
|
|
| term
|
|
)
|
|
term <- or(
|
|
| ParenExpr("(" / expr ")")
|
|
| match_expr
|
|
| null_lit
|
|
| ref_id
|
|
| block
|
|
| num_lit
|
|
| big_num_lit
|
|
| string_lit
|
|
| char_lit
|
|
| query_comprehension
|
|
| array_literal
|
|
)
|
|
basic_name <- or(
|
|
DotExpr(basic_name null(NullCondQualifier) "." / ref_id) | ref_id
|
|
)
|
|
lambda_expr <- LambdaExpr(
|
|
"(" lambda_param_list ")" ?pick(":" type_ref) "=>" / expr
|
|
)
|
|
null_lit <- NullLit("null" / ?pick("[" / type_ref "]"))
|
|
argument <- Argument(?pick(ref_id "=") expr)
|
|
args <- list*(argument, ",")
|
|
decl_annotation_args <- ?DeclAnnotationArgs("(" args ")")
|
|
decl_annotation <- DeclAnnotation("@" / id decl_annotation_args)
|
|
query_comprehension <- Query(
|
|
"from" expr
|
|
"match" pattern
|
|
?pick("select" expr)
|
|
?pick("if" expr)
|
|
)
|
|
}
|