1
我想创建一个简单的HOCON解析器(从现有的JSON之一开始)。Antlr4 - 没有可行的替代输入
语法定义为:
/** Taken from "The Definitive ANTLR 4 Reference" by Terence Parr */
// Derived from http://json.org
grammar HOCON;
hocon
: value
| pair
;
obj
: object_begin pair (','? pair)* object_end
| object_begin object_end
;
pair
: STRING KV? value {fmt.Println("pairstr",$STRING.GetText())}
| KEY KV? value {fmt.Println("pairkey",$KEY.GetText())}
;
array
: array_begin value (',' value)* array_end
| array_begin array_end
;
value
: STRING {fmt.Println($STRING.GetText())}
| REFERENCE {fmt.Println($REFERENCE.GetText())}
| RAWSTRING {fmt.Println($RAWSTRING.GetText())}
| NUMBER {fmt.Println($NUMBER.GetText())}
| obj
| array
| 'true'
| 'false'
| 'null'
;
COMMENT
: '#' ~('\r' | '\n')* -> skip
;
STRING
: '"' (ESC | ~ ["\\])* '"'
| '\'' (ESC | ~ ['\\])* '\''
;
RAWSTRING
: (ESC | ALPHANUM)+
;
KEY
: ('.' | ALPHANUM | '-')+
;
REFERENCE
: '${' (ALPHANUM|'.')+ '}'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment ALPHANUM
: [0-9a-zA-Z]
;
fragment HEX
: [0-9a-fA-F]
;
KV
: [=:]
;
array_begin
: '[' { fmt.Println("BEGIN [") }
;
array_end
: ']' { fmt.Println("] END") }
;
object_begin
: '{' { fmt.Println("OBJ {") }
;
object_end
: '}' { fmt.Println("} OBJ") }
;
NUMBER
: '-'? INT '.' [0-9] + EXP? | '-'? INT EXP | '-'? INT
;
fragment INT
: '0' | [1-9] [0-9]*
;
// no leading zeros
fragment EXP
: [Ee] [+\-]? INT
;
// \- since - means "range" inside [...]
WS
: [ \t\n\r] + -> skip
;
错误是:
line 2:2 no viable alternative at input '{journal'
pairkey akka.persistence
样品输入,使该错误是:
akka.persistence {
journal {
# Absolute path to the journal plugin configuration entry used by
# persistent actor or view by default.
# Persistent actor or view can override `journalPluginId` method
# in order to rely on a different journal plugin.
plugin = ""
}
}
但是如果我将更新它使用带引号的字符串:
akka.persistence {
'journal' {
# Absolute path to the journal plugin configuration entry used by
# persistent actor or view by default.
# Persistent actor or view can override `journalPluginId` method
# in order to rely on a different journal plugin.
'plugin' = ""
}
}
一切按预期工作。
看起来我错过了KEY
定义中的一些东西,但我无法真正发现究竟是什么。
的Go代码来测试它是:
package main
import (
"github.com/antlr/antlr4/runtime/Go/antlr"
"go-hocon/parser"
)
func main() {
is, _ := antlr.NewFileStream("test/simple1.conf")
lex := parser.NewHOCONLexer(is)
p := parser.NewHOCONParser(antlr.NewCommonTokenStream(lex, 0))
p.BuildParseTrees = true
p.Hocon()
}
谢谢!我创建了repo https://github.com/jdevelop/go-hocon - 我可以通过将'rawstring'从令牌转换为解析器来解决这个问题。这有助于 - 但是我现在正在与测试案例交战,应该将原始字符串作为对象中的值捕获。例如,如果第11行更新时不带引号,则此测试[config](https://github.com/jdevelop/go-hocon/blob/master/test/simple1.conf)失败。 – jdevelop