C#的Antlr4问题。正在消失的错误消息

C#的Antlr4问题。正在消失的错误消息,c#,antlr4,C#,Antlr4,我想使用Antlr4构建一个GraphQL解析器。目标语言是C#。这是我第一次尝试使用Antlr 我找到了GraphQL语法。已将其加载到并尝试使用以下输入文件运行它: query queryName($foo: ComplexType, $site: Site = MOBILE) { whoever123is: node(id: [123, 456]) { id , ... on User @defer { field2 { id ,

我想使用Antlr4构建一个GraphQL解析器。目标语言是C#。这是我第一次尝试使用Antlr

我找到了GraphQL语法。已将其加载到并尝试使用以下输入文件运行它:

query queryName($foo: ComplexType, $site: Site = MOBILE) {
  whoever123is: node(id: [123, 456]) {
    id ,
    ... on User @defer {
      field2 {
        id ,
        alias: field1(first:10, after:$foo,) @include(if: $foo) {
          id,
          ...frag
        }
      }
    }
    ... @skip(unless: $foo) {
      id
    }
    ... {
      id
    }
  }
}

Error is not reported Here. Parser just stops

mutation likeStory {
  like(story: 123) @defer {
    story {
      id
    }
  }
}
正如所料,我在单词“error”处出现了一个错误:

line 29:26 token recognition error at: '. '
[@0,295:299='query',<17>,8:0]
[@1,301:309='queryName',<29>,8:6]
[@2,310:310='(',<6>,8:15]
[@3,311:311='$',<14>,8:16]
[@4,312:314='foo',<29>,8:17]
[@5,315:315=':',<5>,8:20]
[@6,317:327='ComplexType',<29>,8:22]
[@7,330:330='$',<14>,8:35]
[@8,331:334='site',<29>,8:36]
[@9,335:335=':',<5>,8:40]
[@10,337:340='Site',<29>,8:42]
[@11,342:342='=',<8>,8:47]
[@12,344:349='MOBILE',<29>,8:49]
[@13,350:350=')',<3>,8:55]
[@14,352:352='{',<10>,8:57]
[@15,357:368='whoever123is',<29>,9:2]
[@16,369:369=':',<5>,9:14]
[@17,371:374='node',<29>,9:16]
[@18,375:375='(',<6>,9:20]
[@19,376:377='id',<29>,9:21]
[@20,378:378=':',<5>,9:23]
[@21,380:380='[',<4>,9:25]
[@22,381:383='123',<30>,9:26]
[@23,386:388='456',<30>,9:31]
[@24,389:389=']',<1>,9:34]
[@25,390:390=')',<3>,9:35]
[@26,392:392='{',<10>,9:37]
[@27,399:400='id',<29>,10:4]
[@28,409:411='...',<9>,11:4]
[@29,413:414='on',<2>,11:8]
[@30,416:419='User',<29>,11:11]
[@31,421:421='@',<7>,11:16]
[@32,422:426='defer',<29>,11:17]
[@33,428:428='{',<10>,11:23]
[@34,437:442='field2',<29>,12:6]
[@35,444:444='{',<10>,12:13]
[@36,455:456='id',<29>,13:8]
[@37,469:473='alias',<29>,14:8]
[@38,474:474=':',<5>,14:13]
[@39,476:481='field1',<29>,14:15]
[@40,482:482='(',<6>,14:21]
[@41,483:487='first',<29>,14:22]
[@42,488:488=':',<5>,14:27]
[@43,489:490='10',<30>,14:28]
[@44,493:497='after',<29>,14:32]
[@45,498:498=':',<5>,14:37]
[@46,499:499='$',<14>,14:38]
[@47,500:502='foo',<29>,14:39]
[@48,504:504=')',<3>,14:43]
[@49,506:506='@',<7>,14:45]
[@50,507:513='include',<29>,14:46]
[@51,514:514='(',<6>,14:53]
[@52,515:516='if',<29>,14:54]
[@53,517:517=':',<5>,14:56]
[@54,519:519='$',<14>,14:58]
[@55,520:522='foo',<29>,14:59]
[@56,523:523=')',<3>,14:62]
[@57,525:525='{',<10>,14:64]
[@58,538:539='id',<29>,15:10]
[@59,553:555='...',<9>,16:10]
[@60,556:559='frag',<29>,16:13]
[@61,570:570='}',<11>,17:8]
[@62,579:579='}',<11>,18:6]
[@63,586:586='}',<11>,19:4]
[@64,593:595='...',<9>,20:4]
[@65,597:597='@',<7>,20:8]
[@66,598:601='skip',<29>,20:9]
[@67,602:602='(',<6>,20:13]
[@68,603:608='unless',<29>,20:14]
[@69,609:609=':',<5>,20:20]
[@70,611:611='$',<14>,20:22]
[@71,612:614='foo',<29>,20:23]
[@72,615:615=')',<3>,20:26]
[@73,617:617='{',<10>,20:28]
[@74,626:627='id',<29>,21:6]
[@75,634:634='}',<11>,22:4]
[@76,641:643='...',<9>,23:4]
[@77,645:645='{',<10>,23:8]
[@78,654:655='id',<29>,24:6]
[@79,662:662='}',<11>,25:4]
[@80,667:667='}',<11>,26:2]
[@81,670:670='}',<11>,27:0]
[@82,675:679='Error',<29>,29:0]
[@83,681:682='is',<29>,29:6]
[@84,684:686='not',<29>,29:9]
[@85,688:695='reported',<29>,29:13]
[@86,697:700='Here',<29>,29:22]
[@87,703:708='Parser',<29>,29:28]
[@88,710:713='just',<29>,29:35]
[@89,715:719='stops',<29>,29:40]
[@90,724:731='mutation',<18>,31:0]
[@91,733:741='likeStory',<29>,31:9]
[@92,743:743='{',<10>,31:19]
[@93,748:751='like',<29>,32:2]
[@94,752:752='(',<6>,32:6]
[@95,753:757='story',<29>,32:7]
[@96,758:758=':',<5>,32:12]
[@97,760:762='123',<30>,32:14]
[@98,763:763=')',<3>,32:17]
[@99,765:765='@',<7>,32:19]
[@100,766:770='defer',<29>,32:20]
[@101,772:772='{',<10>,32:26]
[@102,779:783='story',<29>,33:4]
[@103,785:785='{',<10>,33:10]
[@104,794:795='id',<29>,34:6]
[@105,802:802='}',<11>,35:4]
[@106,807:807='}',<11>,36:2]
[@107,810:810='}',<11>,37:0]
[@108,813:812='<EOF>',<-1>,38:0]
line 29:0 extraneous input 'Error' expecting {<EOF>, '{', 'fragment', 'query', 'mutation', 'schema', 'scalar', 'type', 'interface', 'enum', 'union', 'input', 'extend', 'directive'}
(document (definition (operationDefinition (operationType query) (name queryName) (variableDefinitions ((variableDefinition (variable $ (name foo)) : (type (typeName (name ComplexType)))) (variableDefinition (variable $ (name site)) : (type (typeName (name Site))) (defaultValue = (value (enumValue (name MOBILE))))) )) (selectionSet { (selection (field (alias (name whoever123is) :) (name node) (arguments ((argument (name id) : (valueWithVariable (arrayValueWithVariable[(valueWithVariable 123) (valueWithVariable 456) ]))) )) (selectionSet { (selection (field (name id))) (selection (inlineFragment... (typeCondition on (typeName (name User))) (directives (directive @ (name defer))) (selectionSet { (selection (field (name field2) (selectionSet { (selection (field (name id))) (selection (field (alias (name alias) :) (name field1) (arguments ((argument (name first) : (valueWithVariable 10)) (argument (name after) : (valueWithVariable (variable $ (name foo)))) )) (directives (directive @ (name include) (arguments ((argument (name if) : (valueWithVariable (variable $ (name foo)))) )))) (selectionSet { (selection (field (name id))) (selection (fragmentSpread... (fragmentName (name frag)))) }))) }))) }))) (selection (inlineFragment... (directives (directive @ (name skip) (arguments ((argument (name unless) : (valueWithVariable (variable $ (name foo)))) )))) (selectionSet { (selection (field (name id))) }))) (selection (inlineFragment... (selectionSet { (selection (field (name id))) }))) }))) }))) Error is not reported Here Parser just stops(definition (operationDefinition (operationType mutation) (name likeStory) (selectionSet { (selection(field(name like)(arguments((argument(name story) : (valueWithVariable 123))))(directives(directive @ (name defer))) (selectionSet { (selection(field(name story)(selectionSet { (selection(field(name id))) }))) }))) }))))
第29行:26处的令牌识别错误:'.'
[@0295:299='query',8:0]
[@1301:309='queryName',8:6]
[@2,310:310='(',,8:15]
[@3,311:311='$',,8:16]
[@4312:314='foo',8:17]
[@5,315:315=':',,8:20]
[@6317:327='ComplexType',8:22]
[@7,330:330='$',,8:35]
[@8331:334='site',8:36]
[@9,335:335=':',,8:40]
[@10337:340='Site',8:42]
[@11,342:342='=',,8:47]
[@12344:349='MOBILE',8:49]
[@13,350:350=')',,8:55]
[@14,352:352='{',,8:57]
[@15357:368='whoever123is',9:2]
[@16,369:369=':',,9:14]
[@17371:374='node',9:16]
[@18,375:375='(',,9:20]
[@19376:377='id',9:21]
[@20,378:378=':',,9:23]
[@21,380:380='[',,9:25]
[@22,381:383='123',,9:26]
[@23,386:388='456',,9:31]
[@24,389:389=']',,9:34]
[@25,390:390=')',,9:35]
[@26,392:392='{',,9:37]
[@27399:400='id',10:4]
[@28,409:411='...',,11:4]
[@29413:414='on',11:8]
[@30416:419='User',11:11]
[@31,421:421='@',,11:16]
[@32422:426='defer',11:17]
[@33,428:428='{',,11:23]
[@34437:442='field2',12:6]
[@35,444:444='{',,12:13]
[@36455:456='id',13:8]
[@37469:473='alias',14:8]
[@38,474:474=':',,14:13]
[@39476:481='field1',14:15]
[@40,482:482='(',,14:21]
[@41483:487='first',14:22]
[@42,488:488=':',,14:27]
[@43,489:490='10',,14:28]
[@44493:497='after',14:32]
[@45,498:498=':',,14:37]
[@46,499:499='$',,14:38]
[@47500:502='foo',14:39]
[@48,504:504=')',,14:43]
[@49,506:506='@',,14:45]
[@50507:513='include',14:46]
[@51,514:514='(',,14:53]
[@52515:516='if',14:54]
[@53,517:517=':',,14:56]
[@54,519:519='$',,14:58]
[@55520:522='foo',14:59]
[@56,523:523=')',,14:62]
[@57,525:525='{',,14:64]
[@58538:539='id',15:10]
[@59,553:555='...',,16:10]
[@60556:559='frag',16:13]
[@61,570:570='}',,17:8]
[@62,579:579='}',,18:6]
[@63,586:586='}',,19:4]
[@64,593:595='...',,20:4]
[@65,597:597='@',,20:8]
[@66598:601='skip',20:9]
[@67,602:602='(',,20:13]
[@68603:608='除非',20:14]
[@69,609:609=':',,20:20]
[@70,611:611='$',,20:22]
[@71612:614='foo',20:23]
[@72,615:615=')',,20:26]
[@73,617:617='{',,20:28]
[@74626:627='id',21:6]
[@75,634:634='}',,22:4]
[@76,641:643='...',,23:4]
[@77,645:645='{',,23:8]
[@78654:655='id',24:6]
[@79,662:662='}',,25:4]
[@80,667:667='}',,26:2]
[@81,670:670='}',,27:0]
[@82675:679='Error',29:0]
[@83681:682='is',29:6]
[@84684:686='not',29:9]
[@85688:695='reported',29:13]
[@86697:700='此处',29:22]
[@87703:708='Parser',29:28]
[@88710:713='just',29:35]
[@89715:719='stops',29:40]
[@90724:731='mutation',31:0]
[@91733:741='likeStory',31:9]
[@92,743:743='{',,31:19]
[@93748:751='like',32:2]
[@94,752:752='(',,32:6]
[@95753:757='story',32:7]
[@96,758:758=':',,32:12]
[@97,760:762='123',,32:14]
[@98,763:763=')',,32:17]
[@99,765:765='@',,32:19]
[@100766:770='defer',32:20]
[@101,772:772='{',,32:26]
[@102779:783='story',33:4]
[@103,785:785='{',,33:10]
[@104794:795='id',34:6]
[@105,802:802='}',,35:4]
[@106,807:807='}',,36:2]
[@107,810:810='}',,37:0]
[@108,813:812='',,38:0]
第29行:0外部输入“错误”应为{,{,{,},{,,“片段”,“查询”,“变异”,“架构”,“标量”,“类型”,“接口”,“枚举”,“联合”,“输入”,“扩展”,“指令”}
文档(定义(操作定义(操作类型查询)(名称查询名称)(变量定义(变量$(名称foo)):(类型(类型名称(名称复合类型))))(变量定义(变量$(名称站点)):(类型(类型名称(名称站点)))(默认值=(值(枚举值(名称移动())))(选择集{(选择)(字段(别名(名称whoever123is):)(名称节点)(参数((参数(名称id):(valueWithVariable[(valueWithVariable 123)(valueWithVariable 456)]))))(选择集{(选择(字段(名称id)))(选择(inlineFragment…(typeName用户)上的typeCondition)(指令@(名称延迟)))(selectionSet{(selection(field)(name field2)(selectionSet{(selection(field(name id))))(selection(field)(别名)(name别名):)(name field1)(实参((实参(name first):(valueWithVariable 10))(实参(name after):(valueWithVariable(variable$(name foo))))(指令@(name include)(实参((实参)(名称if):(valueWithVariable(variable$(name foo))))))(selectionSet{(selection(field(name id)))(selection(fragmentSpread…(fragmentName(name frag))))})(selection(inlineFragment…(指令@(name skip)(参数((参数(名称除外):(valueWithVariable(variable$(name foo)))))))(selectionSet{(selection(field(name id)))})(selection(inlineFragment…(selectionSet{(selection(field(name id)))})))此处不报告错误解析器只是停止(定义(operationDefinition(operationType突变)(name LikeStore)(selectionSet{(selection)(field(name like))参数((参数(name story):(valueWithVariable 123)))(指令(指令@(名称延迟)))(选择集{(选择(字段(名称故事)(选择集{(字段(名称id)))})))})
所以,我使用这个语法来生成源代码(CSharp目标)

问题是: 如果输入不包含任何错误,我的解析器可以正常工作。但是如果输入类似于上面的示例,它会自动停止,不会显示/抛出任何错误。生成的树只包含一个元素(在错误输入之前解析的所有内容)

我尝试创建不同的错误侦听器,更改恢复策略等。没有任何东西会改变这种行为


非常感谢您的任何帮助。

您需要实现一个BailErrorStrategy,该策略将覆盖ANTLR4从错误中恢复的能力

1) 加载一个严格的lexer

    AntlrInputStream inputStream = new AntlrInputStream(stream);
    BailLexer lexer = new BailLexer(inputStream);
2) 加载严格的解析器:

    parser.RemoveErrorListeners();
    parser.ErrorHandler = new StrictErrorStrategy();
3) 创建一个bailexer类(随意调用
    public override void Recover(LexerNoViableAltException e)
    {
        throw new ParseCanceledException(BasicEnvironment.SyntaxError);
    }
public class StrictErrorStrategy : DefaultErrorStrategy
{
    public override void Recover(Parser recognizer, RecognitionException e)
    {
        throw new Exception(message, e);
    }


    public override IToken RecoverInline(Parser recognizer)
    {
        throw new Exception(message, new InputMismatchException(recognizer));
    }


    public override void Sync(Parser recognizer) { }
}