public static AST.HashValue.Item Parse(CharStream stream) { var startingPos = stream.Position; try { // check if a hash item is supposed to be a default bool isDefault = stream.SkipIfPossible('*'); // parse the raw identifier (key) var identifier = Identifier.Parse(stream, false); // whitespace is optional WhiteSpace.Parse(stream, true); // the seperator char is required as it seperates the key and the value stream.SkipCharacter(':'); // more optional whitespace WhiteSpace.Parse(stream, true); // get the actual value, which is identified by the key var value = Value.Parse(stream); return new AST.HashValue.Item(identifier, value, isDefault); } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <hash_item> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { // skip open char stream.SkipCharacter('['); // we need at least one index var index = new AST.Index(ParseExpression(stream)); // others are optional while (stream.SkipIfPossible(',')) { index.AddIndex(ParseExpression(stream)); } // skip close char stream.SkipCharacter(']'); return index; } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <index> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static void Parse( CharStream stream, string identifier, Internal.LocaleContext.Builder builder) { var startingPos = stream.Position; try { var macroAST = new AST.Macro(identifier); stream.SkipCharacter('('); WhiteSpace.Parse(stream, true); // variables are optional, // but we do have them, we need at least one (duh) if (Expressions.Variable.Peek(stream)) { macroAST.AddParameter(Macro.ParseVariable(stream)); // more than 1 is possible as well while (stream.SkipIfPossible(',')) { WhiteSpace.Parse(stream, true); macroAST.AddParameter(Macro.ParseVariable(stream)); } } stream.SkipCharacter(')'); WhiteSpace.Parse(stream, false); stream.SkipCharacter('{'); WhiteSpace.Parse(stream, true); // Parse the Actual Macro Expression macroAST.SetExpression(Expression.Parse(stream)); WhiteSpace.Parse(stream, true); stream.SkipCharacter('}'); WhiteSpace.Parse(stream, true); stream.SkipCharacter('>'); // return the fully parsed macro try { var macro = (Objects.Macro)macroAST.Eval(); builder.AddMacro(identifier, macro); } catch (Exception e) { throw new Exceptions.EvaluateException( String.Format("couldn't evaluate `{0}`", macroAST.Display()), e); } } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <macro> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { AST.INode root; if(!Property.PeekAndParse(stream, out root)) { root = IdentifierExpression.Parse(stream); } stream.SkipString("::"); // we either have an expression or a simple identifier AST.INode identifier; if (stream.SkipIfPossible('[')) { identifier = Expression.Parse(stream); stream.SkipCharacter(']'); } else { identifier = new AST.Identifier(Identifier.Parse(stream, false)); } // We can also have optionally a property expression, // starting with a simple identifier or straight away with an expression AST.PropertyExpression propertyExpression = null; if (stream.SkipIfPossible('.')) { propertyExpression = Property.Parse(stream) as AST.PropertyExpression; } else if (stream.SkipIfPossible('[')) { var expression = Expression.Parse(stream); propertyExpression = new AST.PropertyExpression(expression); stream.SkipCharacter(']'); Property.Parse(stream, propertyExpression); } return new AST.AttributeExpression(root, identifier, propertyExpression); } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <property_expression> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static void Parse(CharStream stream) { if (!stream.SkipIfPossible('/') || !(stream.SkipIfPossible('*'))) { throw stream.CreateException( "a comment has to be opened with '/*'"); } char c; string content = ""; while (stream.ReadNext(out c)) { if (c == '*' && stream.SkipIfPossible('/')) { return; } content += c; } throw new ParseException( "a comment entry was opened, but not closed", stream.CreateEOFException()); }
public static AST.INode Parse(CharStream stream, AST.INode member) { var startingPos = stream.Position; try { // skip opening tag stream.SkipCharacter('('); WhiteSpace.Parse(stream, true); var call = new AST.CallExpression(member); // parse arguments if possible if (!stream.SkipIfPossible(')')) { call.AddParameter(ParseExpression(stream)); // but we can also have moreß while (stream.SkipIfPossible(',')) { call.AddParameter(ParseExpression(stream)); } // skip closing tag stream.SkipCharacter(')'); } return call; } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <call_expression> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { if (stream.SkipIfPossible('(')) { var e = Expression.Parse(stream); stream.SkipCharacter(')'); return e; } else { // than we /should/ have a primary expressions return Primary.Parse(stream); } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <parenthesis_expression> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { // skip opening tag stream.SkipCharacter('{'); // at least 1 hashItem is required with optional whitespace surrounding it var hashValue = new AST.HashValue(); WhiteSpace.Parse(stream, true); hashValue.AddItem(HashItem.Parse(stream)); WhiteSpace.Parse(stream, true); // parse all other (optional) hashItems while (stream.SkipIfPossible(',')) { if (!HashValue.ParseHashItem(stream, hashValue)) { // if we have a trailing comma, it will be break here break; } } // skip closing tag stream.SkipCharacter('}'); return hashValue; } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <hash_value> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static void Parse(CharStream stream, Internal.LocaleContext.Builder builder) { var startingPos = stream.Position; try { if (Comment.PeekAndParse(stream)) return; // normally we keep the requirements of a format for a parser internal, // but in this case we have the same start for both a <macro> and an <entity> // so we simply have to make an exception in this case for performance reasons if (stream.SkipIfPossible('<')) { var identifier = Identifier.Parse(stream, true); if (Macro.PeekAndParse(stream, identifier, builder)) return; // now it NEEDS to be a entitiy, else our input is simply invalid // knowing that we are already on a path of no return // because of the fact that we started parsing '<' and an identifier. Entity.Parse(stream, identifier, builder); } else { // it has to be an import statement at this point ImportStatement.Parse(stream, builder); } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <entry> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new ParseException(msg, e); } }