grammar JASON; json: object | array ; object : '{' pair ( ',' pair )* '}' # AnObject | '{' '}' # EmptyObject ; pair: STRING':'value; array : '['value(','value)*']' # ArrayOfValues | '['']' # EmptyArray ; value : STRING # String | NUMBER # Atom | object # ObjectValue | array # ArrayValue | 'true' # Atom | 'false' # Atom | 'null' # Atom ; STRING : '"' ( ESC | ~["\\] )* '"'; fragment ESC: '\\'(["\\/bfnrt]|UNICODE); fragment UNICODE:'u'HEX HEX HEX HEX; fragment HEX:[0-9a-fA-F]; NUMBER : '-'? INT'.'INT EXP? //1.35,1.35E-9,0.3,-4.5 | '-'? INT EXP //1e10-3e4 | '-'? INT //-3,45 ; fragment INT: '0'|[1-9][0-9]*;//noleadingzeros fragment EXP: [Ee][+\-]? INT;//\-since-means"range"inside[...] WS : [\t\n\r]+->skip;
class XmlListener : JASONBaseListener { #region fields ParseTreeProperty<XElement> xml = new ParseTreeProperty<XElement>(); #endregion #region result public XElement Root { get; private set; } #endregion #region xml api XElement GetXml( IParseTree ctx ) { return xml.Get( ctx ); } /// <summary> /// xml /// </summary> XElement GetParentXml( IParseTree ctx ) { var parent = ctx.Parent; XElement result = GetXml( parent ); if ( result == null ) result = GetParentXml( parent ); return result; } void SetXml( IParseTree ctx, XElement e ) { xml.Put( ctx, e ); } #endregion #region listener public override void ExitString( JASONParser.StringContext context ) { var value = GetStringValue( context.STRING() ); AddValue( context, value ); } public override void ExitAtom( JASONParser.AtomContext context ) { var value = context.GetText(); AddValue( context, value ); } public override void EnterPair( JASONParser.PairContext context ) { var name = GetStringValue( context.STRING() ); XElement element = new XElement( name ); XElement ParentElement = GetParentXml( context ); ParentElement.Add( element ); SetXml( context, element ); } public override void EnterJson( JASONParser.JsonContext context ) { Root = new XElement( "JSON" ); SetXml( context, Root); } #endregion #region private private string GetStringValue( ITerminalNode terminal ) { return terminal.GetText().Trim( '"' ); } private void AddValue( ANTLR_CSV.JASONParser.ValueContext context, string value ) { var parent = GetParentXml( context ); if ( context.Parent.RuleIndex == JASONParser.RULE_array ) { XElement element = new XElement( "elemnt" ); element.Value = value; parent.Add( element ); SetXml( context, element ); } else parent.Value = value; } #endregion }
json: object | array ;
STRING # String
class XmlVisitor : JASONBaseVisitor<XElement> { #region fields private XElement _result; ParseTreeProperty<XElement> xml = new ParseTreeProperty<XElement>(); #endregion #region xml api XElement GetXml( IParseTree ctx ) { return xml.Get( ctx ); } XElement GetParentXml( IParseTree ctx ) { var parent = ctx.Parent; XElement result = GetXml( parent ); if ( result == null ) result = GetParentXml( parent ); return result; } void SetXml( IParseTree ctx, XElement e ) { xml.Put( ctx, e ); } #endregion #region visitor /// <summary> /// - xml /// </summary> protected override XElement DefaultResult { get { return _result; } } public override XElement VisitJson( JASONParser.JsonContext context ) { _result = new XElement( "JSON" ); SetXml( context, _result ); return VisitChildren( context ); } public override XElement VisitString( JASONParser.StringContext context ) { var value = GetStringValue( context.STRING() ); AddValue( context, value ); return DefaultResult; } public override XElement VisitAtom( JASONParser.AtomContext context ) { var value = context.GetText(); AddValue( context, value ); return DefaultResult; } public override XElement VisitPair( JASONParser.PairContext context ) { var name = GetStringValue( context.STRING() ); XElement element = new XElement( name ); XElement ParentElement = GetParentXml( context ); ParentElement.Add( element ); SetXml( context, element ); return VisitChildren( context ); } #endregion #region private private string GetStringValue( ITerminalNode terminal ) { return terminal.GetText().Trim( '"' ); } private void AddValue( ANTLR_CSV.JASONParser.ValueContext context, string value ) { var parent = GetParentXml( context ); if ( context.Parent.RuleIndex == JASONParser.RULE_array ) { XElement element = new XElement( "elemnt" ); element.Value = value; parent.Add( element ); SetXml( context, element ); } else parent.Value = value; } #endregion }
var result = visitor.Visit( tree );
walker.Walk( listener, tree ); var result = listener.Root;
private static IParseTree CreateTree() { StringBuilder sb = new StringBuilder(); sb.AppendLine( "{" ); sb.AppendLine( "\"description\":\"Animaginary server config file\"," ); sb.AppendLine( "\"count\":500," ); sb.AppendLine( "\"logs\":{\"level\":\"verbose\",\"dir\":\"/var/log\"}," ); sb.AppendLine( "\"host\":\"antlr.org\"," ); sb.AppendLine( "\"admin\":[\"parrt\",\"tombu\"]," ); sb.AppendLine( "\"aliases\":[]" ); sb.AppendLine( "}" ); AntlrInputStream input = new AntlrInputStream( sb.ToString() ); JASONLexer lexer = new JASONLexer( input ); CommonTokenStream tokens = new CommonTokenStream( lexer ); JASONParser parser = new JASONParser( tokens ); IParseTree tree = parser.json(); return tree; }
private static void ListenerXml() { IParseTree tree = CreateTree(); ParseTreeWalker walker = new ParseTreeWalker(); XmlListener listener = new XmlListener(); walker.Walk( listener, tree ); var result = listener.Root; } private static void VisitorXml() { IParseTree tree = CreateTree(); XmlVisitor visitor = new XmlVisitor(); var result = visitor.Visit( tree ); }
<JSON> <description>Animaginary server config file</description> <count>500</count> <logs> <level>verbose</level> <dir>/var/log</dir> </logs> <host>antlr.org</host> <admin> <elemnt>parrt</elemnt> <elemnt>tombu</elemnt> </admin> <aliases /> </JSON>
Source: https://habr.com/ru/post/259691/
All Articles