public static void Parse( CharStream stream, string identifier, Internal.LocaleContext.Builder builder) { var startingPos = stream.Position; try { // private identifiers start with an underscore // and can only be referenced from within an l20n file bool isPrivate = (identifier.IndexOf('_') == 0); // an optional index is possible AST.INode index = null; Index.PeekAndParse(stream, out index); // White Space is required WhiteSpace.Parse(stream, false); var valuePos = stream.Position; // Now we need the actual value var value = Value.Parse(stream); if ((value as IO.AST.HashValue) == null && index != null) { string msg = String.Format( "an index was given, but a stringValue was given, while a hashValue was expected", stream.ComputeDetailedPosition(valuePos)); throw new Exceptions.ParseException(msg); } // an optional attributes collection is possible AST.Attributes attributes; Attributes.PeekAndParse(stream, out attributes); // White Space is optional WhiteSpace.Parse(stream, true); stream.SkipCharacter('>'); var entityAST = new AST.Entity(identifier, isPrivate, index, value, attributes); try { var entity = (Objects.Entity)entityAST.Eval(); builder.AddEntity(identifier, entity); } catch (Exception e) { throw new Exceptions.EvaluateException( String.Format("couldn't evaluate `{0}`", entityAST.Display()), e); } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <entity> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static Info Parse(CharStream stream, Info expected = null) { string output; int pos = stream.Position; if (!stream.ReadReg("(\'|\")", out output)) { throw new Exceptions.ParseException( String.Format( "expected to read a <quote> (starting at {0}), but no characters were left", stream.ComputeDetailedPosition(pos))); } Info info; if (output[0] == '"') { info = new Info(Type.Double); } else { info = new Info(Type.Single); } if (expected != null && expected.CompareTo(info) != 0) { throw new Exceptions.ParseException( String.Format( "expected to read {0} (starting at {1}), but found {2}", expected.ToString(), stream.ComputeDetailedPosition(pos), info.ToString())); } return info; }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { var first = Binary.Parse(stream); string op; if (stream.ReadReg(@"\s*(\|\||\&\&)", out op)) { WhiteSpace.Parse(stream, true); var second = Logic.Parse(stream); return new AST.LogicExpression( first, second, op.Trim()); } else { return first; } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <logical_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 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 AST.INode Parse(CharStream stream) { var startingPos = stream.Position; AST.INode expression = null; try { // skip opening tags stream.SkipString("{{"); WhiteSpace.Parse(stream, true); // parse actual expression expression = Expression.Parse(stream); // skip closing tags WhiteSpace.Parse(stream, true); stream.SkipString("}}"); return expression; } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <expander> starting at {0}, expression was: {1} ({2})", stream.ComputeDetailedPosition(startingPos), expression != null ? expression.Display() : "<null>", expression != null ? expression.GetType().ToString() : "null"); throw new Exceptions.ParseException(msg, e); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { var condition = Expressions.Logic.Parse(stream); // check if we have an IfElse case or simply a logical expression string s; if (stream.ReadReg(@"\s*\?\s*", out s)) { var first = Expression.Parse(stream); WhiteSpace.Parse(stream, true); stream.SkipCharacter(':'); WhiteSpace.Parse(stream, true); var second = Expression.Parse(stream); return new AST.Conditional(condition, first, second); } else { // it's simply a logical expression return condition; } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <expression> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static string Parse(CharStream stream) { var startingPos = stream.Position; try { var output = ""; var quote = Quote.Parse(stream); char c; while ((c = stream.PeekNext()) != '\0') { if (c == '\\') { output += stream.ForceReadNext(); } else if (Quote.Peek(stream, quote)) { break; // un-escaped quote means we're ending the string } output += stream.ForceReadNext(); } Quote.Parse(stream, quote); return output; } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <string_value> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
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 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.Attributes.Item Parse(CharStream stream) { var startingPos = stream.Position; try { WhiteSpace.Parse(stream, false); // parse the raw identifier (key) var identifier = Identifier.Parse(stream, false); // parse the index if possible AST.INode index; Index.PeekAndParse(stream, out index); WhiteSpace.Parse(stream, true); // required seperator stream.SkipCharacter(':'); WhiteSpace.Parse(stream, true); var valuePos = stream.Position; // the actual value (StringValue or HashTable) var value = Value.Parse(stream); if ((value as IO.AST.HashValue) == null && index != null) { string msg = String.Format( "an index was given, but a stringValue was given, while a hashValue was expected", stream.ComputeDetailedPosition(valuePos)); throw new Exceptions.ParseException(msg); } return new AST.Attributes.Item(identifier, index, value); } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <key_value_pair> 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, Internal.LocaleContext.Builder builder) { var startingPos = stream.Position; try { stream.SkipString("import("); WhiteSpace.Parse(stream, true); var path = PureStringValue.Parse(stream); WhiteSpace.Parse(stream, true); stream.SkipCharacter(')'); LocalizableObjectsList.ImportAndParse(path, builder); } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <import_statement> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
public static AST.Attributes Parse(CharStream stream) { var startingPos = stream.Position; try { var attributes = new AST.Attributes(); AST.Attributes.Item item; while (KeyValuePair.PeekAndParse(stream, out item)) { attributes.AddItem(item); } return attributes; } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <attributes> 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 value; if (!Value.PeekAndParse(stream, out value)) { throw new Exceptions.ParseException( "couldn't find valid <value> type"); } return value; } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <value> 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 primary; if (Literal.PeekAndParse(stream, out primary)) return primary; if (Value.PeekAndParse(stream, out primary)) return primary; return IdentifierExpression.Parse(stream); } catch (Exception e) { string msg = String.Format( "something went wrong parsing a <primary> 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, AST.PropertyExpression property = null) { var startingPos = stream.Position; try { if (property == null) { var obj = IdentifierExpression.Parse(stream); property = new AST.PropertyExpression(obj); } char c; // can be either a simple identifier ('.') or expression ('[') while (stream.SkipAnyIfPossible(new char[] {'.', '['}, out c)) { if (c == '.') { property.Add(Identifier.Parse(stream, false)); } else { WhiteSpace.Parse(stream, true); property.Add(Expression.Parse(stream)); WhiteSpace.Parse(stream, true); stream.SkipCharacter(']'); } } return property; } 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 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 AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { var first = Unary.Parse(stream); string raw; if (stream.ReadReg(@"\s*(\=\=|\!\=|\<\=|\>\=|\<|\>|\+|\-|\*|\/|\%)", out raw)) { var chain = new Chain(stream, first, raw); return chain.Build(); } else { return first; } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <binary_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 { char op; if (stream.SkipAnyIfPossible(new char[3]{'+', '-', '!'}, out op)) { WhiteSpace.Parse(stream, true); var expression = Unary.Parse(stream); return new AST.UnaryOperation(expression, op); } else { return Member.Parse(stream); } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <unary_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 { AST.INode identifier; if (Variable.PeekAndParse(stream, out identifier)) return identifier; if (Global.PeekAndParse(stream, out identifier)) return identifier; return new AST.Identifier( Identifier.Parse(stream, true)); } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <identifier> 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); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { AST.INode expression; if (Attribute.PeekAndParse(stream, out expression)) // an attribute expression is always seperated by '::' and optionally with square brackets // around the actual attribute identifier, that allows the use of an expression { return expression; } else if (Property.PeekAndParse(stream, out expression)) // a property expression is always seperated by a dot (`.`) or embraced by square brackets // and has to have at least 1 property (e.g.: `x.y` or `x[y]`), // more than 1 is also acceptable (e.g.: `x.y.z` or `x[y][z]` or `x[y].z` or `x.y[z]`). { return expression; } else { var member = Parenthesis.Parse(stream); if (Call.PeekAndParse(stream, member, out expression)) return expression; return member; } } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <member_expression> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
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 { // Parse the quote and store that in the AST of the stringValue var quote = Quote.Parse(stream); var value = new AST.StringValue(quote); AST.INode expression; char c; // Trim starting space WhiteSpace.Parse(stream, true); // as long as we have more characters left // we'll keep reading, and break from within this loop body // when we reached the same quote that started this entire parser logic. while ((c = stream.PeekNext()) != '\0') { if (c == '\\') { // skip the escape character && read the next one stream.Skip(); c = stream.PeekNext(); if (c == '\\' || c == '{' || c == '}' || c == '\'' || c == '"') { c = stream.ForceReadNext(); value.appendChar(c); } else if (c == 'u') { // skip the starter character stream.Skip(); // try to read unicode character value.appendChar(ReadUnicodeCharacter(stream)); } else { var msg = String.Format( "character \\{0} is not a valid escape character", c); throw stream.CreateException(msg); } // unicode characters are also supported in the classical U+xxxxxx notation } else if (c == 'U' && stream.PeekNext(1) == '+') { // skip the starter characters stream.Skip(2); // try to read unicode character value.appendChar(ReadUnicodeCharacter(stream)); } else if (c == '\n' || c == '\r') // newlines get converted to a space { stream.Skip(); var lc = value.LastCharacter; // we add this dummy character, such that we wouldn't add a space in // languages that don't use a space in general, such as chinese. if (!Char.IsWhiteSpace(lc) && lc != AST.StringValue.DummyNewlineWhitespaceCharacter) value.appendChar(AST.StringValue.DummyNewlineWhitespaceCharacter); } else { if (Quote.Peek(stream, quote)) { break; // un-escaped quote means we're ending the string } else if (Expander.PeekAndParse(stream, out expression)) { value.appendExpression(expression); } else { c = stream.ForceReadNext(); var lc = value.LastCharacter; if(!Char.IsWhiteSpace(c) || (lc != AST.StringValue.DummyNewlineWhitespaceCharacter && !Char.IsWhiteSpace(lc))) value.appendChar(c); } } } // Eventually we expect exactly the same string back Quote.Parse(stream, quote); return value; } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <string_value> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }