/// <summary> /// Transforms a string containing a handlebars.js-compatible template into a template syntax tree /// </summary> /// <param name="templateText"></param> /// <param name="t"></param> /// <returns></returns> internal RootNode Parse(string templateText, Template t) { // Todo: rewrite this as a monadic parser combinator? // http://blogs.msdn.com/b/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx // http://lorgonblog.wordpress.com/2007/12/02/c-3-0-lambda-and-the-first-post-of-a-series-about-monadic-parser-combinators/ // http://nblumhardt.com/2010/01/building-an-external-dsl-in-c/ (using sprache) try { // init context and rules var parserContext = new ParserContext(t); var textConsumer = new ParserTextConsumer(templateText); var rules = new ParserRules(parserContext); while (textConsumer.Consume()) { IRule rule = rules.Match(textConsumer.NextFragment); rule.ProcessContext(); } return parserContext.RootNode; } catch (Exception ex) { throw new Exception("An error occurred while parsing the provided template text:", ex); } }
public ParserContext(ParserRules rules, TokenizerContext reader) { this.rules = rules; this.reader = reader; reader.Next(); }
public void IgnorePrefixes_CanParseFileWithComments_NoExceptionsThrown() { var daRules = new ParserRules(); daRules.CommentIndicators.Add(new Tuple <string, string>("#", "\n")); string jsonText = ResourceFetcher.GetText("_TestData/WithComments.json"); Json json = JsonHelper.ParseText(jsonText, daRules); Assert.IsNotNull(json); Assert.IsFalse(json.HasErrors, "Json parse errors:\n" + String.Join("\n\t", json.Errors)); }
public void IgnorePrefixes_CanParseFileWithComments_BlockComment_ParsedProperly() { var daRules = new ParserRules(); daRules.CommentIndicators.Add(new Tuple <string, string>("/*", "*/")); string jsonText = ResourceFetcher.GetText("_TestData/WithBlockComments.json"); Json result = JsonHelper.ParseText(jsonText, daRules); Assert.IsNotNull(result); Assert.IsNotNull(result.Data); Assert.IsFalse(result.HasErrors); }
public void TestMethod3() { Fetcher f = new Fetcher(); var result = f.Execute <dynamic>("http://jsonplaceholder.typicode.com/posts", new RestRequest()); //var resultset = result.Data as IEnumerable<dynamic>; var ruleSet = new ParserRules(); ruleSet.Fields.Add(new Field { Selector = "id" }); Parser p = new Parser(); var parseResult = p.Parse(result, ruleSet); var serialized = SimpleJson.SerializeObject(parseResult); }
public dynamic Get(string id) { FeedManager fm = new FeedManager(Settings); var feed = fm.Get(id).Result; var request = new GetRequest { Feed = feed.RemoteFeed, Fields = new List <Field>() }; string[] fields = feed.Fields.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var field in fields) { request.Fields.Add(new Field { Selector = field }); } if (string.IsNullOrWhiteSpace(request.Feed)) { throw new ApplicationException("feed param empty"); } if (request.Fields == null) { throw new ApplicationException("no fields"); } Fetcher f = new Fetcher(); var result = f.Execute <dynamic>(request.Feed, new RestRequest()); //var resultset = result.Data as IEnumerable<dynamic>; var ruleSet = new ParserRules(); ruleSet.Fields.AddRange(request.Fields); //foreach (var field in fields) //{ // ruleSet.Fields.Add(new Field { Selector = field }); //} Parser p = new Parser(); var parseResult = p.Parse(result, ruleSet); return(parseResult); //var serialized = SimpleJson.SerializeObject(parseResult); //return "value"; }
//Break input into corresponding lexemes public SyntaxToken Lex() { //End of File if (_position >= _text.Length) { return(new SyntaxToken(TokenType.EndOfFile, _position, "\0", null)); } var start = _position; //Integer if (char.IsDigit(Current)) { while (char.IsDigit(Current)) { Next(); } var length = _position - start; var text = _text.Substring(start, length); if (!int.TryParse(text, out var value)) { _diagnostics.ReportInvalidNumber(new TextSpan(start, length), _text, typeof(int)); } return(new SyntaxToken(TokenType.Number, start, text, value)); } //Whitespace if (char.IsWhiteSpace(Current)) { while (char.IsWhiteSpace(Current)) { Next(); } var length = _position - start; var text = _text.Substring(start, length); return(new SyntaxToken(TokenType.Whitespace, start, text, null)); } //True-False and catch-all identifiers if (char.IsLetter(Current)) { while (char.IsLetter(Current)) { Next(); } var length = _position - start; var text = _text.Substring(start, length); var kind = ParserRules.GetKeywordKind(text); return(new SyntaxToken(kind, start, text, null)); } //TODO refactor this for readability & scalability //Operators - Arithmetic & Binary switch (Current) { //Arithmetic Operators case '+': return(new SyntaxToken(TokenType.Plus, _position++, "+", null)); case '-': return(new SyntaxToken(TokenType.Minus, _position++, "-", null)); case '*': return(new SyntaxToken(TokenType.Star, _position++, "*", null)); case '/': return(new SyntaxToken(TokenType.Slash, _position++, "/", null)); case '\\': return(new SyntaxToken(TokenType.ReverseSlash, _position++, "/", null)); case '%': return(new SyntaxToken(TokenType.Modulo, _position++, "%", null)); case '^': return(new SyntaxToken(TokenType.BitwiseXor, _position++, "^", null)); case '#': return(new SyntaxToken(TokenType.Power, _position++, "^", null)); //Boolean Operators case '!': { switch (Ahead) { case '=': _position += 2; return(new SyntaxToken(TokenType.Negation, start, "!=", null)); default: return(new SyntaxToken(TokenType.Negation, start, "!", null)); } } case '&': { switch (Ahead) { case '&': _position += 2; return(new SyntaxToken(TokenType.LogicalAnd, start, "&&", null)); default: return(new SyntaxToken(TokenType.BitwiseAnd, _position++, "&", null)); } } case '|': { switch (Ahead) { case '|': _position += 2; return(new SyntaxToken(TokenType.LogicalOr, start, "||", null)); default: return(new SyntaxToken(TokenType.BitwiseOr, _position++, "&", null)); } } case '=': { switch (Ahead) { //We haven't implemented the assignment operator case '=': _position += 2; return(new SyntaxToken(TokenType.Equality, start, "==", null)); default: return(new SyntaxToken(TokenType.Assign, _position++, "=", null)); } } case '>': { switch (Ahead) { case '=': _position += 2; return(new SyntaxToken(TokenType.GreaterThanEquals, start, ">=", null)); case '>': _position += 2; return(new SyntaxToken(TokenType.RightShift, start, ">>", null)); default: return(new SyntaxToken(TokenType.GreaterThan, _position++, ">", null)); } } case '<': { switch (Ahead) { case '=': _position += 2; return(new SyntaxToken(TokenType.LessThanEquals, start, "<=", null)); case '<': _position += 2; return(new SyntaxToken(TokenType.LeftShift, start, "<<", null)); default: return(new SyntaxToken(TokenType.LessThan, _position++, "<", null)); } } case '~': return(new SyntaxToken(TokenType.BitwiseNegation, _position++, "~", null)); case '(': return(new SyntaxToken(TokenType.OpenParenthesis, _position++, "(", null)); case ')': return(new SyntaxToken(TokenType.CloseParenthesis, _position++, ")", null)); } _diagnostics.ReportBadCharacter(_position, Current); return(new SyntaxToken(TokenType.Bad, _position++, _text.Substring(_position - 1, 1), null)); }