Antlr程序无法编译

时间:2013-11-28 00:07:08

标签: antlr antlrworks

我正在尝试使用语法来解析json语言

我用来了解每个条目http://www.json.com

的自动机的链接
grammar myjson;

prog
    : object+ EOF
    ;

object
    : '{'
        STRING  ':' value 
        (','  STRING  ':' value)*
      '}'
    | '{' EMPTY '}'
    ;

array
    : '[' 
        value 
        (',' value)* 
      ']'
    | '[' EMPTY ']
    ; 

value
    : object | STRING | NUMBER
    | array | BOOL | NULL
    ;

STRING
    : '"' (UNICODE | SPECIAL)* '"'
    ;

UNICODE
    : ~('\u0022' | '\u005C')
    ;

SPECIAL     
    : '\u005C'
      (
      | '"' | '\u005C'  | '\u002F'
      | 'b' | 'f' | 'n' | 'r'
      | 't' | 'u' DIGIT DIGIT DIGIT DIGIT
      )
    ;

NULL: 'null';
BOOL
    : 'true'
    | 'false'
    ;   


NUMBER : ('+'|'-')? DIGIT+ '.' DIGIT* EXPONENT?
       | ('+'|'-')? '.'? DIGIT+ EXPONENT?
       ;

fragment 
EXPONENT : ('e' | 'E') ('+' | '-') ? DIGIT+ 
         ;

fragment
DIGIT  : '0'..'9' 
       ;

fragment
LETTER
    : ('a'..'z' | 'A'..'Z')
    ;

COMM
    : '//' ~('\r'? '\n')   {skip();}    
    | '/*' .* '*/'         {skip();}
    ;

WS
    : ' ' | '\t' | '\r' | '\n' | '\u000c' {skip();} 
    ;

EMPTY
    : ''
    ;   

我想声明我正在使用antlrworks v 1.4.3,因为这是我老师建议使用的。

我的问题是这个语法甚至不会编译,因为我得到以下错误

java.util.NoSuchElementException: can't look backwards more than one token in this stream
    at org.antlr.runtime.misc.LookaheadStream.LB(LookaheadStream.java:159)
    at org.antlr.runtime.misc.LookaheadStream.LT(LookaheadStream.java:120)
    at org.antlr.runtime.RecognitionException.extractInformationFromTreeNodeStream(RecognitionException.java:144)
    at org.antlr.runtime.RecognitionException.<init>(RecognitionException.java:111)
    at org.antlr.runtime.MismatchedTreeNodeException.<init>(MismatchedTreeNodeException.java:42)
    at org.antlr.runtime.tree.TreeParser.recoverFromMismatchedToken(TreeParser.java:135)
    at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
    at org.antlr.grammar.v3.TreeToNFAConverter.alternative(TreeToNFAConverter.java:2798)
    at org.antlr.grammar.v3.TreeToNFAConverter.block(TreeToNFAConverter.java:2662)
    at org.antlr.grammar.v3.TreeToNFAConverter.rule(TreeToNFAConverter.java:1995)
    at org.antlr.grammar.v3.TreeToNFAConverter.rules(TreeToNFAConverter.java:1338)
    at org.antlr.grammar.v3.TreeToNFAConverter.grammarSpec(TreeToNFAConverter.java:1288)
    at org.antlr.grammar.v3.TreeToNFAConverter.grammar_(TreeToNFAConverter.java:319)
    at org.antlr.tool.Grammar.buildNFA(Grammar.java:1006)
    at org.antlr.tool.CompositeGrammar.createNFAs(CompositeGrammar.java:390)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createLexerGrammarFromCombinedGrammar(ANTLRGrammarEngineImpl.java:219)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createCombinedGrammar(ANTLRGrammarEngineImpl.java:204)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createGrammars(ANTLRGrammarEngineImpl.java:165)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.analyze(ANTLRGrammarEngineImpl.java:272)
    at org.antlr.works.grammar.engine.GrammarEngineImpl.analyze(GrammarEngineImpl.java:325)
    at org.antlr.works.debugger.local.DBLocal.analyzeGrammar(DBLocal.java:385)
    at org.antlr.works.debugger.local.DBLocal.generateAndCompileGrammar(DBLocal.java:365)
    at org.antlr.works.debugger.local.DBLocal.run(DBLocal.java:222)
    at java.lang.Thread.run(Unknown Source)

我在一篇文章中读到“不能向后看多个令牌中的一个令牌”java异常,即词法分析器和解析器语法不匹配,但我不知道它是什么或它引用的是什么。我也为不评论代码而道歉。但我不太了解antlr因此我不想写一些可能让你失望的东西。

请提前帮助并谢谢

1 个答案:

答案 0 :(得分:1)

你的语法有几个错误:

  • 从不匹配(可能)匹配空字符串的标记:当您的词法分析器尝试匹配它们时,它将进入无限循环。简而言之:删除EMPTY令牌
  • ' ' | '\t' | '\r' | '\n' | '\u000c' {skip();}相当于' ' | '\t' | '\r' | '\n' | ('\u000c' {skip();})。你想做的是:(' ' | '\t' | '\r' | '\n' | '\u000c') {skip();}而不是
  • 您的SPECIAL规则与单个反斜杠匹配:'\u005C' ( /* NOTHING HERE */ | '"' | ...:删除第一个|'\u005C' ( '"' | ...
  • 否定字符集必须包含单个字符,而不是像您所做的那样包含两个字符:~('\r'? '\n')*(您不能否定\r\n)。它应该是:~('\r' | '\n')*

尝试这样的事情(未经测试!):

grammar myjson;

prog
 : object+ EOF
 ;

object
 : '{' (key_value (',' key_value)*)? '}'
 ;

array
 : '[' (value (',' value)*)? ']'
 ;

key_value
 : STRING ':' value
 ;

value
 : object
 | array
 | STRING
 | NUMBER
 | BOOL
 | NULL 
 ;

NULL
 : 'null'   
 ;

BOOL
 : 'true'
 | 'false'
 ;

STRING
  : '"' (UNICODE | SPECIAL)* '"'
  ;

NUMBER
 : ('+'|'-')? DIGIT+ '.' DIGIT* EXPONENT?
 | ('+'|'-')? '.'? DIGIT+ EXPONENT?
 ;

COMM
 : '//' ~('\r' | '\n')* {skip();}    
 | '/*' .* '*/'         {skip();}
 ;

SPACE
 : (' ' | '\t' | '\r' | '\n' | '\u000c')+ {skip();}
 ;

fragment
DIGIT
 : '0'..'9' 
 ;

fragment 
EXPONENT 
 : ('e' | 'E') ('+' | '-') ? DIGIT+ 
 ;

fragment
UNICODE
 : ~('\u0022' | '\u005C') 
 ;

fragment
SPECIAL     
 : '\u005C' ( '"' | '\u005C'  | '\u002F'
            | 'b' | 'f' | 'n' | 'r'
            | 't' | 'u' DIGIT DIGIT DIGIT DIGIT
            )
 ;

同时检查来自ANTLR Github存储库的JSON语法:https://github.com/antlr/grammars-v4/blob/master/json/Json.g4虽然是ANTLR4语法,但它看起来与ANTLR 3兼容。