如何在语法工具包中使用关键字作为标识符来解决中的歧义



我一直在尝试为grammarkit编写graphql语言语法,但我发现自己已经陷入了相当长一段时间的歧义问题。graphql中的关键字(如:typeimplementsscalar)也可以是类型或字段的名称。即

type type implements type {}

起初,我在bnf中将这些关键字定义为tokens,但这意味着上面的情况是无效的。但如果我在描述规则时直接写下这些关键词,就会导致语法歧义。我在下面看到的一个基于这个语法的问题的例子是,如果你定义了这样的

directive @foo on Baz | Bar
scalar Foobar @cool

PSI查看器告诉我,在@cool的位置上,它期望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?

一旦语法看到directive @TOKEN on IDENTIFIER,它就会消耗一个DirectiveAddtlLocation序列。其中每一个都由一个可选的CCD_ 9和一个CCD_。正如您在问题中所注意到的,GraphQL"关键字"实际上只是标识符的特殊情况。因此,这里可能发生的情况是,由于您允许任何令牌作为标识符,scalarFoobar都被消耗为DirectiveAddtlLocation,而它实际上从未看到ScalarTypeDef

# Parses the same as:
directive @foo on Bar | Baz | scalar | Foobar
@cool  # <-- ?????

你可以通过在语法中列出一组明确的允许指令位置来解决这个问题。(只需复制GraphQL规范附录B中的语法并更改其语法,您甚至可以走得更远。)

DirectiveLocation ::= ExecutableDirectiveLocation | TypeSystemDirectiveLocation
ExecutableDirectiveLocation ::= 'QUERY' | 'MUTATION' | ...
TypeSystemDirectiveLocation ::= 'SCHEMA' | 'SCALAR' | ...

现在,当你去解析:

directive @foo on QUERY | MUTATION
# "scalar" is not a directive location, so the DirectiveTypeDef must end
scalar Foobar @cool

(尽管"标识符"one_answers"关键字"的区别有点奇怪,但我敢肯定GraphQL语法实际上并没有歧义;在允许自由格式标识符的每一个上下文中,在"关键字"再次出现之前都会有标点符号,在这种情况下,会有不完全重叠的不完全关键字的明确列表。)

相关内容

  • 没有找到相关文章

最新更新