public override string ToString() { switch (this.type) { case TypeOf.Null: return("Null"); // + " -> NULL"; case TypeOf.True: return("true"); // + " -> bool"; case TypeOf.False: return("false"); // + " -> bool"; case TypeOf.String: return(this.sValue); // + " -> String"; case TypeOf.Number: return(this.nValue.ToString()); // + " -> Number"; case TypeOf.Comment: return("//" + this.representation); // + " -> Comment"; case TypeOf.Root: return(this.ToStructure()); case TypeOf.rList: var r = new ralyn(); r.Children = this.Children; return(r.ToStructure()); default: return(""); } }
public ralyn Path(string path) { //Console.WriteLine($"searching {this.Tag.name} for {path}"); ralyn result = this; var directions = path.Split(new char[] { '>' }); var count = 0; foreach (var step in directions) { //Console.WriteLine($"step:{step}"); ++count; if (step == "*") { //create list of ralyn elements var subresult = new ralyn(); var subresultChildren = new List <ralyn>(); foreach (var item in result.Children) { var newDirections = String.Join(">", directions.Skip(count).Take(directions.Length - count).ToArray()); if (item.Type != ralyn.TypeOf.Comment && String.IsNullOrEmpty(item.error)) { var subPathReturns = item.Path(newDirections); if (subPathReturns != null) { subPathReturns.Tag.name = ""; subresultChildren.Add(subPathReturns); } } } subresult.Children = subresultChildren; return(subresult); } else { if (step.StartsWith("[") && step.EndsWith("]")) { int index; bool success = Int32.TryParse(step.Trim(new char[] { '[', ']' }), out index); if (!success) { //Console.WriteLine("INVALID PATH - index NaN"); return(null); } foreach (var item in result.Children) { if (index < 0) { //Console.WriteLine("INVALID PATH - index less than Zero"); return(null); } if (item.Type != ralyn.TypeOf.Comment && String.IsNullOrEmpty(item.error)) { if (index == 0) { result = item; break; } else { --index; } } } if (index > 0) { //Console.WriteLine("INVALID PATH - index out of range"); return(null); } continue; } var foundPath = false; foreach (var item in result.Children) { //Console.WriteLine($"\titem:{item.Tag.name}"); if (item.Type == ralyn.TypeOf.Comment || !String.IsNullOrEmpty(item.error)) { continue; } if (item.Tag.name == step) { foundPath = true; result = item; break; } } if (!foundPath) { //Console.WriteLine($"INVALID PATH - could not find {step}"); return(null); } } } return(result); }
private static List <ralyn> Lex(string code) { //setup vars var rObj = new List <ralyn>(); string line; using (var _code = new System.IO.StringReader(code)) { #region vars var accumulator = new StringBuilder(); var stringBeginSequence = ""; var stringEndSequence = ""; var currentTypeOf = ralyn.TypeOf.Undetermined; var currentValue = new ralyn(); var ids = new List <string>(); var nestLevel = 0; var isComment = false; #endregion vars while (_code.Peek() > -1) { line = _code.ReadLine();//.Trim(); ++currentValue.LineNumber; currentValue.CharNumber = -1; if (accumulator.Length > 0) { accumulator.AppendLine(""); } foreach (char c in line) { ++currentValue.CharNumber; if (currentTypeOf == ralyn.TypeOf.Undetermined && ( c == ':' || c == ' ')) { continue; } accumulator.Append(c); //Console.WriteLine(lineNum.ToString() + ":" + charNum.ToString() + " " + accumulator.ToString() + "->" + currentTypeOf.ToString()); if (currentTypeOf == ralyn.TypeOf.Undetermined) { currentTypeOf = ralyn.looksLike(accumulator.ToString()); } if (currentTypeOf == ralyn.TypeOf.Undetermined) { continue; } //OK, we think we know what we are dealing with switch (currentTypeOf) { #region simple value lexing case ralyn.TypeOf.Null: currentValue.Value = "null"; rObj.Add(currentValue); //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); break; case ralyn.TypeOf.True: currentValue.Value = "true"; rObj.Add(currentValue); //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); break; case ralyn.TypeOf.False: currentValue.Value = "false"; rObj.Add(currentValue); //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); break; case ralyn.TypeOf.Tag: //end condition is >: if (c == '>') { currentValue.Tag = new ralyn.ralynTag(accumulator.ToString()); if (currentValue.Tag.name.Contains('*') || currentValue.Tag.name.Contains('[') || currentValue.Tag.name.Contains(']') || currentValue.Tag.name.Contains('.') || currentValue.Tag.name.Contains('<') || currentValue.Tag.name.Contains('-') || currentValue.Tag.name.Contains('!') || currentValue.Tag.name.Contains('@') || currentValue.Tag.name.Contains('#') || currentValue.Tag.name.Contains('$') ) { currentValue.error = $"Tag name <{currentValue.Tag.name}> contains illegal characters: ['*', '[', ']', '.', '<', '-', '!', '@', '#', '$']"; } if (ids.Contains(currentValue.Tag.name)) { //this tag name already exists at this level... trigger error currentValue.error = $"Tag name <{currentValue.Tag.name}> appears multiple times"; } else { ids.Add(currentValue.Tag.name); } //reset -- sort of accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; //currentValue = new ralynValue(); //DON'T REST THE ENTIRE VALUE! } break; case ralyn.TypeOf.Number: #region Number lexing //keep accumulating until encouter , or ; if (c == ',' || c == ';' || c == ' ' || currentValue.CharNumber == line.Length - 1) { if (c == ',' || c == ';' || c == ' ') { accumulator.Length--; //nerf delimiter } if (accumulator[0] == ':') { currentValue.Value = accumulator.ToString().Substring(1); } else { currentValue.Value = accumulator.ToString(); } rObj.Add(currentValue); //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); } #endregion Number lexing break; case ralyn.TypeOf.String: #region String lexing #region String boundary conditions var test = accumulator.ToString().Trim().TrimStart(new char[] { ':', ' ', '\t' }); if (stringBeginSequence == "" && test.Length > 0 && test[0] == '"') { stringBeginSequence = "\""; stringEndSequence = "\""; } else if (stringBeginSequence == "" && test.Length > 0 && test[0] == '\'') { stringBeginSequence = "\'"; stringEndSequence = "\'"; } else if (stringBeginSequence == "" && test.Length > 2 && test[0] == '$' && test[1] == '(') { stringBeginSequence = "$(" + test[2].ToString(); stringEndSequence = test[2].ToString() + ")"; } #endregion String boundary conditions //accumulate until encounter string end condition if (test.Length >= 2 && stringEndSequence != "" && test.ToString().EndsWith(stringEndSequence) && !test.ToString().EndsWith("\\" + stringEndSequence) ) { currentValue.Value = test.ToString(); rObj.Add(currentValue); //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); stringBeginSequence = ""; stringEndSequence = ""; } #endregion String lexing break; #endregion simple value lexing case ralyn.TypeOf.Comment: isComment = true; accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; break; case ralyn.TypeOf.rList: if (c == '{') { ++nestLevel; } if (c == '}') { --nestLevel; } if (nestLevel == 0) { if (!isComment) { //currentValue.Value = Lex(accumulator.ToString().Trim(new char[] { '{', '}' })); currentValue.Children = Lex(accumulator.ToString().Trim(new char[] { '{', '}' })); rObj.Add(currentValue); } else { //currentValue.Type = ralynValue.TypeOf.Comment; currentValue.Value = "//" + accumulator.ToString(); rObj.Add(currentValue); } //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); isComment = false; } break; case ralyn.TypeOf.ControlCharacter: //ignore for now //reset accumulator.Length = 0; currentTypeOf = ralyn.TypeOf.Undetermined; currentValue = new ralyn(); break; default: break; } } } } //check for mixed mode var mode = ""; foreach (var r in rObj) { if (r.Type == ralyn.TypeOf.Comment) { continue; } var tagCheck = false; var noTagCheck = false; if (String.IsNullOrEmpty(r.Tag.name)) { noTagCheck = true; if (mode == "") { mode = "non-associative"; } } else { tagCheck = true; if (mode == "") { mode = "associative"; } } if (tagCheck && mode == "non-associative") { r.error = "unexpected tag in non-associative object"; } if (noTagCheck && mode == "associative") { r.error = "missing tag in associative object"; } } return(rObj); }
//UI static void Main(string[] args) { var exit = false; var fileName = @"..\..\TestCode.ralyn"; while (!exit) { Console.Clear(); Console.WriteLine("ralyn Builder"); Console.WriteLine($" 1. Select File (current file->{fileName})"); Console.WriteLine(" 2. Format RALYN"); Console.WriteLine(" 3. Transpile to JSON"); Console.WriteLine(" 4. Transpile to XML"); Console.WriteLine(" 5. Path"); Console.WriteLine(" 0. Exit"); var key = Console.ReadKey(); string codeFromFile = System.IO.File.ReadAllText(fileName); ralyn ralynDoc = new ralyn(); switch (key.KeyChar) { case '1': Console.WriteLine(); Console.WriteLine("Enter new file path"); var tempFile = Console.ReadLine(); var fi = new System.IO.FileInfo(tempFile); if (fi.Exists) { fileName = tempFile; } else { Console.WriteLine($"Could not locate {tempFile}, reverting to {fileName}"); Console.WriteLine("press any key to continue..."); Console.ReadKey(); } break; case '2': //Format RALYN Console.WriteLine(); ralynDoc = new ralyn(codeFromFile); Console.WriteLine(ralynDoc); Console.WriteLine("press any key to continue..."); Console.ReadKey(); break; case '3': //Transpile to JSON Console.WriteLine(); ralynDoc = new ralyn(codeFromFile); Console.WriteLine(ralynDoc.ToJSON()); Console.WriteLine("press any key to continue..."); Console.ReadKey(); break; case '4': //Transpile to XML Console.WriteLine(); ralynDoc = new ralyn(codeFromFile); Console.WriteLine(ralynDoc.ToXML()); Console.WriteLine("press any key to continue..."); Console.ReadKey(); break; case '5': //Path Console.WriteLine(); Console.WriteLine("Enter path... something like ralyn>record-1>a"); var path = Console.ReadLine(); ralynDoc = new ralyn(codeFromFile); Console.WriteLine(ralynDoc.Path(path)); Console.WriteLine("press any key to continue..."); Console.ReadKey(); break; case '0': exit = true; break; default: break; } } }