我一直在尝试为 Grammarkit 编写 graphql 语言语法,但我发现自己在很长一段时间内都陷入了歧义问题。graphql 中的关键字(例如:、、、type
)implements
也scalar
可以是类型或字段的名称。IE
type type implements type {}
起初我tokens
在 bnf 中定义了这些关键字,但这意味着上面的情况是无效的。但是如果我在描述规则时直接写这些关键字,就会导致语法上的歧义。我根据下面的语法看到的一个问题示例是,如果您定义了这样的内容
directive @foo on Baz | Bar
scalar Foobar @cool
PSI 查看器告诉我,在@cool
它的位置期待 a DirectiveAddtlLocation
,这是我什至在标量规则中都没有引用的规则。有没有人熟悉语法包并遇到过这样的事情?我真的很感激一些见解。谢谢你。
这是我上面提到的错误示例的语法摘录。
{
tokens=[
LEFT_PAREN='('
RIGHT_PAREN=')'
PIPE='|'
AT='@'
IDENTIFIER="regexp:[_A-Za-z][_0-9A-Za-z]*"
WHITE_SPACE = 'regexp:\s+'
]
}
Document ::= Definition*
Definition ::= DirectiveTypeDef | ScalarTypeDef
NamedTypeDef ::= IDENTIFIER
// I.E. @foo @bar(a: 10) @baz
DirectivesDeclSet ::= DirectiveDecl+
DirectiveDecl ::= AT TypeName
// I.E. directive @example on FIELD_DEFINITION | ARGUMENT_DEFINITION
DirectiveTypeDef ::= 'directive' AT NamedTypeDef DirectiveLocationsConditionDef
DirectiveLocationsConditionDef ::= 'on' DirectiveLocation DirectiveAddtlLocation*
DirectiveLocation ::= IDENTIFIER
DirectiveAddtlLocation ::= PIPE? DirectiveLocation
TypeName ::= IDENTIFIER
// I.E. scalar DateTime @foo
ScalarTypeDef ::= 'scalar' NamedTypeDef DirectivesDeclSet?