private Expression ParseGroup(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken token = tokenizer.current; if (token.type != StyleSyntaxTokenType.OpenBracket) { throw new Exception($"Unexpected token '{token.type}' in group expression. Expected '[' token"); } m_CombinatorStack.Push(ExpressionCombinator.Group); tokenizer.MoveNext(); EatSpace(tokenizer); var subExpression = ParseExpression(tokenizer); token = tokenizer.current; if (token.type != StyleSyntaxTokenType.CloseBracket) { throw new Exception($"Unexpected token '{token.type}' in group expression. Expected ']' token"); } // Do not eat the space after the ] token because it could be a juxtaposition or multiplier tokenizer.MoveNext(); var group = new Expression(ExpressionType.Combinator); group.combinator = ExpressionCombinator.Group; group.subExpressions = new Expression[] { subExpression }; ParseMultiplier(tokenizer, ref group.multiplier); return(group); }
private static bool IsCombinator(StyleSyntaxToken token) { StyleSyntaxTokenType type = token.type; StyleSyntaxTokenType styleSyntaxTokenType = type; return(styleSyntaxTokenType - StyleSyntaxTokenType.Space <= 3); }
private Expression ParseGroup(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken current = tokenizer.current; bool flag = current.type != StyleSyntaxTokenType.OpenBracket; if (flag) { throw new Exception(string.Format("Unexpected token '{0}' in group expression. Expected '[' token", current.type)); } this.m_CombinatorStack.Push(ExpressionCombinator.Group); tokenizer.MoveNext(); StyleSyntaxParser.EatSpace(tokenizer); Expression expression = this.ParseExpression(tokenizer); current = tokenizer.current; bool flag2 = current.type != StyleSyntaxTokenType.CloseBracket; if (flag2) { throw new Exception(string.Format("Unexpected token '{0}' in group expression. Expected ']' token", current.type)); } tokenizer.MoveNext(); Expression expression2 = new Expression(ExpressionType.Combinator); expression2.combinator = ExpressionCombinator.Group; expression2.subExpressions = new Expression[] { expression }; this.ParseMultiplier(tokenizer, ref expression2.multiplier); return(expression2); }
private static bool IsExpressionEnd(StyleSyntaxToken token) { StyleSyntaxTokenType type = token.type; StyleSyntaxTokenType styleSyntaxTokenType = type; return(styleSyntaxTokenType == StyleSyntaxTokenType.CloseBracket || styleSyntaxTokenType == StyleSyntaxTokenType.End); }
private void ParseRanges(StyleSyntaxTokenizer tokenizer, out int min, out int max) { min = -1; max = -1; StyleSyntaxToken styleSyntaxToken = tokenizer.current; bool flag = false; while (styleSyntaxToken.type != StyleSyntaxTokenType.CloseBrace) { StyleSyntaxTokenType type = styleSyntaxToken.type; StyleSyntaxTokenType styleSyntaxTokenType = type; if (styleSyntaxTokenType != StyleSyntaxTokenType.Number) { if (styleSyntaxTokenType != StyleSyntaxTokenType.Comma) { throw new Exception(string.Format("Unexpected token '{0}' in expression. Expected ranges token", styleSyntaxToken.type)); } flag = true; } else { bool flag2 = !flag; if (flag2) { min = styleSyntaxToken.number; } else { max = styleSyntaxToken.number; } } styleSyntaxToken = tokenizer.MoveNext(); } tokenizer.MoveNext(); }
private Expression ParseTerm(StyleSyntaxTokenizer tokenizer) { Expression exp = null; StyleSyntaxToken token = tokenizer.current; if (token.type == StyleSyntaxTokenType.LessThan) { // Data type or property exp = ParseDataType(tokenizer); } else if (token.type == StyleSyntaxTokenType.String) { // Keyword exp = new Expression(ExpressionType.Keyword); exp.keyword = token.text.ToLower(); tokenizer.MoveNext(); } else { throw new Exception($"Unexpected token '{token.type}' in expression. Expected term token"); } ParseMultiplier(tokenizer, ref exp.multiplier); return(exp); }
private static bool IsMultiplier(StyleSyntaxToken token) { StyleSyntaxTokenType type = token.type; StyleSyntaxTokenType styleSyntaxTokenType = type; return(styleSyntaxTokenType - StyleSyntaxTokenType.Asterisk <= 4 || styleSyntaxTokenType == StyleSyntaxTokenType.OpenBrace); }
private Expression ParseExpression(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken current = tokenizer.current; while (!StyleSyntaxParser.IsExpressionEnd(current)) { bool flag = current.type == StyleSyntaxTokenType.String || current.type == StyleSyntaxTokenType.LessThan; Expression item; if (flag) { item = this.ParseTerm(tokenizer); } else { bool flag2 = current.type == StyleSyntaxTokenType.OpenBracket; if (!flag2) { throw new Exception(string.Format("Unexpected token '{0}' in expression", current.type)); } item = this.ParseGroup(tokenizer); } this.m_ExpressionStack.Push(item); ExpressionCombinator expressionCombinator = this.ParseCombinatorType(tokenizer); bool flag3 = expressionCombinator > ExpressionCombinator.None; if (flag3) { bool flag4 = this.m_CombinatorStack.Count > 0; if (flag4) { ExpressionCombinator expressionCombinator2 = this.m_CombinatorStack.Peek(); int num = (int)expressionCombinator2; int num2 = (int)expressionCombinator; while (num > num2 && expressionCombinator2 != ExpressionCombinator.Group) { this.ProcessCombinatorStack(); expressionCombinator2 = ((this.m_CombinatorStack.Count > 0) ? this.m_CombinatorStack.Peek() : ExpressionCombinator.None); num = (int)expressionCombinator2; } } this.m_CombinatorStack.Push(expressionCombinator); } current = tokenizer.current; } while (this.m_CombinatorStack.Count > 0) { ExpressionCombinator expressionCombinator3 = this.m_CombinatorStack.Peek(); bool flag5 = expressionCombinator3 == ExpressionCombinator.Group; if (flag5) { this.m_CombinatorStack.Pop(); break; } this.ProcessCombinatorStack(); } return(this.m_ExpressionStack.Pop()); }
private static void EatSpace(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken current = tokenizer.current; bool flag = current.type == StyleSyntaxTokenType.Space; if (flag) { tokenizer.MoveNext(); } }
private Expression ParseProperty(StyleSyntaxTokenizer tokenizer) { Expression exp = null; StyleSyntaxToken token = tokenizer.current; if (token.type != StyleSyntaxTokenType.SingleQuote) { throw new Exception($"Unexpected token '{token.type}' in property expression. Expected ''' token"); } token = tokenizer.MoveNext(); if (token.type != StyleSyntaxTokenType.String) { throw new Exception($"Unexpected token '{token.type}' in property expression. Expected 'string' token"); } string propertyName = token.text; string syntax; if (!StylePropertyCache.TryGetSyntax(propertyName, out syntax)) { throw new Exception($"Unknown property '{propertyName}' <''> expression."); } // Check if it's in the cache first if (!m_ParsedExpressionCache.TryGetValue(syntax, out exp)) { // Expanded property are in a group to honor the precedence rule // Pushing the ExpressionCombinator.Group allow the next call to Parse to stop at this location m_CombinatorStack.Push(ExpressionCombinator.Group); // Recursively call Parse to expand the property syntax exp = Parse(syntax); } token = tokenizer.MoveNext(); if (token.type != StyleSyntaxTokenType.SingleQuote) { throw new Exception($"Unexpected token '{token.type}' in property expression. Expected ''' token"); } token = tokenizer.MoveNext(); if (token.type != StyleSyntaxTokenType.GreaterThan) { throw new Exception($"Unexpected token '{token.type}' in property expression. Expected '>' token"); } var group = new Expression(ExpressionType.Combinator); group.combinator = ExpressionCombinator.Group; group.subExpressions = new Expression[] { exp }; return(group); }
private Expression ParseProperty(StyleSyntaxTokenizer tokenizer) { Expression expression = null; StyleSyntaxToken styleSyntaxToken = tokenizer.current; bool flag = styleSyntaxToken.type != StyleSyntaxTokenType.SingleQuote; if (flag) { throw new Exception(string.Format("Unexpected token '{0}' in property expression. Expected ''' token", styleSyntaxToken.type)); } styleSyntaxToken = tokenizer.MoveNext(); bool flag2 = styleSyntaxToken.type != StyleSyntaxTokenType.String; if (flag2) { throw new Exception(string.Format("Unexpected token '{0}' in property expression. Expected 'string' token", styleSyntaxToken.type)); } string text = styleSyntaxToken.text; string text2; bool flag3 = !StylePropertyCache.TryGetSyntax(text, out text2); if (flag3) { throw new Exception("Unknown property '" + text + "' <''> expression."); } bool flag4 = !this.m_ParsedExpressionCache.TryGetValue(text2, out expression); if (flag4) { this.m_CombinatorStack.Push(ExpressionCombinator.Group); expression = this.Parse(text2); } styleSyntaxToken = tokenizer.MoveNext(); bool flag5 = styleSyntaxToken.type != StyleSyntaxTokenType.SingleQuote; if (flag5) { throw new Exception(string.Format("Unexpected token '{0}' in property expression. Expected ''' token", styleSyntaxToken.type)); } styleSyntaxToken = tokenizer.MoveNext(); bool flag6 = styleSyntaxToken.type != StyleSyntaxTokenType.GreaterThan; if (flag6) { throw new Exception(string.Format("Unexpected token '{0}' in property expression. Expected '>' token", styleSyntaxToken.type)); } return(new Expression(ExpressionType.Combinator) { combinator = ExpressionCombinator.Group, subExpressions = new Expression[] { expression } }); }
private Expression ParseDataType(StyleSyntaxTokenizer tokenizer) { Expression exp = null; StyleSyntaxToken token = tokenizer.current; if (token.type != StyleSyntaxTokenType.LessThan) { throw new Exception($"Unexpected token '{token.type}' in data type expression. Expected '<' token"); } token = tokenizer.MoveNext(); switch (token.type) { case StyleSyntaxTokenType.String: DataType dataType = DataType.None; try { object enumValue = Enum.Parse(typeof(DataType), token.text, true); if (enumValue != null) { dataType = (DataType)enumValue; } } catch (Exception) { throw new Exception($"Unknown data type '{token.text}'"); } exp = new Expression(ExpressionType.Data); exp.dataType = dataType; tokenizer.MoveNext(); break; case StyleSyntaxTokenType.SingleQuote: exp = ParseProperty(tokenizer); break; default: throw new Exception($"Unexpected token '{token.type}' in data type expression"); } token = tokenizer.current; if (token.type != StyleSyntaxTokenType.GreaterThan) { throw new Exception($"Unexpected token '{token.type}' in data type expression. Expected '>' token"); } tokenizer.MoveNext(); return(exp); }
private static bool IsExpressionEnd(StyleSyntaxToken token) { switch (token.type) { case StyleSyntaxTokenType.End: case StyleSyntaxTokenType.CloseBracket: return(true); default: return(false); } }
private Expression ParseDataType(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken styleSyntaxToken = tokenizer.current; bool flag = styleSyntaxToken.type != StyleSyntaxTokenType.LessThan; if (flag) { throw new Exception(string.Format("Unexpected token '{0}' in data type expression. Expected '<' token", styleSyntaxToken.type)); } styleSyntaxToken = tokenizer.MoveNext(); StyleSyntaxTokenType type = styleSyntaxToken.type; StyleSyntaxTokenType styleSyntaxTokenType = type; Expression expression; if (styleSyntaxTokenType != StyleSyntaxTokenType.String) { if (styleSyntaxTokenType != StyleSyntaxTokenType.SingleQuote) { throw new Exception(string.Format("Unexpected token '{0}' in data type expression", styleSyntaxToken.type)); } expression = this.ParseProperty(tokenizer); } else { DataType dataType = DataType.None; try { object obj = Enum.Parse(typeof(DataType), styleSyntaxToken.text, true); bool flag2 = obj != null; if (flag2) { dataType = (DataType)obj; } } catch (Exception) { throw new Exception("Unknown data type '" + styleSyntaxToken.text + "'"); } expression = new Expression(ExpressionType.Data); expression.dataType = dataType; tokenizer.MoveNext(); } styleSyntaxToken = tokenizer.current; bool flag3 = styleSyntaxToken.type != StyleSyntaxTokenType.GreaterThan; if (flag3) { throw new Exception(string.Format("Unexpected token '{0}' in data type expression. Expected '>' token", styleSyntaxToken.type)); } tokenizer.MoveNext(); return(expression); }
private static bool IsCombinator(StyleSyntaxToken token) { switch (token.type) { case StyleSyntaxTokenType.Space: case StyleSyntaxTokenType.SingleBar: case StyleSyntaxTokenType.DoubleBar: case StyleSyntaxTokenType.DoubleAmpersand: return(true); default: return(false); } }
private static bool IsMultiplier(StyleSyntaxToken token) { switch (token.type) { case StyleSyntaxTokenType.Asterisk: case StyleSyntaxTokenType.Plus: case StyleSyntaxTokenType.QuestionMark: case StyleSyntaxTokenType.HashMark: case StyleSyntaxTokenType.ExclamationPoint: case StyleSyntaxTokenType.OpenBrace: return(true); default: return(false); } }
public StyleSyntaxToken PeekNext() { int num = this.m_CurrentTokenIndex + 1; bool flag = this.m_CurrentTokenIndex < 0 || num >= this.m_Tokens.Count; StyleSyntaxToken result; if (flag) { result = new StyleSyntaxToken(StyleSyntaxTokenType.Unknown); } else { result = this.m_Tokens[num]; } return(result); }
private void ParseMultiplier(StyleSyntaxTokenizer tokenizer, ref ExpressionMultiplier multiplier) { StyleSyntaxToken token = tokenizer.current; if (IsMultiplier(token)) { switch (token.type) { case StyleSyntaxTokenType.Asterisk: multiplier.type = ExpressionMultiplierType.ZeroOrMore; break; case StyleSyntaxTokenType.Plus: multiplier.type = ExpressionMultiplierType.OneOrMore; break; case StyleSyntaxTokenType.QuestionMark: multiplier.type = ExpressionMultiplierType.ZeroOrOne; break; case StyleSyntaxTokenType.HashMark: multiplier.type = ExpressionMultiplierType.OneOrMoreComma; break; case StyleSyntaxTokenType.ExclamationPoint: multiplier.type = ExpressionMultiplierType.GroupAtLeastOne; break; case StyleSyntaxTokenType.OpenBrace: multiplier.type = ExpressionMultiplierType.Ranges; break; default: throw new Exception($"Unexpected token '{token.type}' in expression. Expected multiplier token"); } token = tokenizer.MoveNext(); } if (multiplier.type == ExpressionMultiplierType.Ranges) { ParseRanges(tokenizer, out multiplier.min, out multiplier.max); } }
private void ParseMultiplier(StyleSyntaxTokenizer tokenizer, ref ExpressionMultiplier multiplier) { StyleSyntaxToken styleSyntaxToken = tokenizer.current; bool flag = StyleSyntaxParser.IsMultiplier(styleSyntaxToken); if (flag) { switch (styleSyntaxToken.type) { case StyleSyntaxTokenType.Asterisk: multiplier.type = ExpressionMultiplierType.ZeroOrMore; goto IL_A1; case StyleSyntaxTokenType.Plus: multiplier.type = ExpressionMultiplierType.OneOrMore; goto IL_A1; case StyleSyntaxTokenType.QuestionMark: multiplier.type = ExpressionMultiplierType.ZeroOrOne; goto IL_A1; case StyleSyntaxTokenType.HashMark: multiplier.type = ExpressionMultiplierType.OneOrMoreComma; goto IL_A1; case StyleSyntaxTokenType.ExclamationPoint: multiplier.type = ExpressionMultiplierType.GroupAtLeastOne; goto IL_A1; case StyleSyntaxTokenType.OpenBrace: multiplier.type = ExpressionMultiplierType.Ranges; goto IL_A1; } throw new Exception(string.Format("Unexpected token '{0}' in expression. Expected multiplier token", styleSyntaxToken.type)); IL_A1: styleSyntaxToken = tokenizer.MoveNext(); } bool flag2 = multiplier.type == ExpressionMultiplierType.Ranges; if (flag2) { this.ParseRanges(tokenizer, out multiplier.min, out multiplier.max); } }
private ExpressionCombinator ParseCombinatorType(StyleSyntaxTokenizer tokenizer) { var type = ExpressionCombinator.None; StyleSyntaxToken token = tokenizer.current; while (!IsExpressionEnd(token) && type == ExpressionCombinator.None) { StyleSyntaxToken next = tokenizer.PeekNext(); switch (token.type) { case StyleSyntaxTokenType.Space: if (!IsCombinator(next) && next.type != StyleSyntaxTokenType.CloseBracket) { type = ExpressionCombinator.Juxtaposition; } break; case StyleSyntaxTokenType.SingleBar: type = ExpressionCombinator.Or; break; case StyleSyntaxTokenType.DoubleBar: type = ExpressionCombinator.OrOr; break; case StyleSyntaxTokenType.DoubleAmpersand: type = ExpressionCombinator.AndAnd; break; default: throw new Exception($"Unexpected token '{token.type}' in expression. Expected combinator token"); } token = tokenizer.MoveNext(); } // Remove space after the combinator if any EatSpace(tokenizer); return(type); }
private ExpressionCombinator ParseCombinatorType(StyleSyntaxTokenizer tokenizer) { ExpressionCombinator expressionCombinator = ExpressionCombinator.None; StyleSyntaxToken styleSyntaxToken = tokenizer.current; while (!StyleSyntaxParser.IsExpressionEnd(styleSyntaxToken) && expressionCombinator == ExpressionCombinator.None) { StyleSyntaxToken styleSyntaxToken2 = tokenizer.PeekNext(); switch (styleSyntaxToken.type) { case StyleSyntaxTokenType.Space: { bool flag = !StyleSyntaxParser.IsCombinator(styleSyntaxToken2) && styleSyntaxToken2.type != StyleSyntaxTokenType.CloseBracket; if (flag) { expressionCombinator = ExpressionCombinator.Juxtaposition; } break; } case StyleSyntaxTokenType.SingleBar: expressionCombinator = ExpressionCombinator.Or; break; case StyleSyntaxTokenType.DoubleBar: expressionCombinator = ExpressionCombinator.OrOr; break; case StyleSyntaxTokenType.DoubleAmpersand: expressionCombinator = ExpressionCombinator.AndAnd; break; default: throw new Exception(string.Format("Unexpected token '{0}' in expression. Expected combinator token", styleSyntaxToken.type)); } styleSyntaxToken = tokenizer.MoveNext(); } StyleSyntaxParser.EatSpace(tokenizer); return(expressionCombinator); }
public StyleSyntaxToken MoveNext() { StyleSyntaxToken current = this.current; bool flag = current.type == StyleSyntaxTokenType.Unknown; StyleSyntaxToken result; if (flag) { result = current; } else { this.m_CurrentTokenIndex++; current = this.current; bool flag2 = this.m_CurrentTokenIndex == this.m_Tokens.Count; if (flag2) { this.m_CurrentTokenIndex = -1; } result = current; } return(result); }
private Expression ParseTerm(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken current = tokenizer.current; bool flag = current.type == StyleSyntaxTokenType.LessThan; Expression expression; if (flag) { expression = this.ParseDataType(tokenizer); } else { bool flag2 = current.type == StyleSyntaxTokenType.String; if (!flag2) { throw new Exception(string.Format("Unexpected token '{0}' in expression. Expected term token", current.type)); } expression = new Expression(ExpressionType.Keyword); expression.keyword = current.text.ToLower(); tokenizer.MoveNext(); } this.ParseMultiplier(tokenizer, ref expression.multiplier); return(expression); }
// Implementation of the shunting yard algorithm private Expression ParseExpression(StyleSyntaxTokenizer tokenizer) { StyleSyntaxToken token = tokenizer.current; while (!IsExpressionEnd(token)) { // Step 1 : either a term or group Expression expression = null; if (token.type == StyleSyntaxTokenType.String || token.type == StyleSyntaxTokenType.LessThan) { expression = ParseTerm(tokenizer); } else if (token.type == StyleSyntaxTokenType.OpenBracket) { expression = ParseGroup(tokenizer); } else { throw new Exception($"Unexpected token '{token.type}' in expression"); } m_ExpressionStack.Push(expression); // Step 2 : either a combinator or the end of the expression var nextCombinatorType = ParseCombinatorType(tokenizer); if (nextCombinatorType != ExpressionCombinator.None) { if (m_CombinatorStack.Count > 0) { var previousCombinator = m_CombinatorStack.Peek(); int previousPrecedence = (int)previousCombinator; int currentPrecedence = (int)nextCombinatorType; // Higher precedence means the previous combinator needs to be created first while (previousPrecedence > currentPrecedence && previousCombinator != ExpressionCombinator.Group) { ProcessCombinatorStack(); previousCombinator = m_CombinatorStack.Count > 0 ? m_CombinatorStack.Peek() : ExpressionCombinator.None; previousPrecedence = (int)previousCombinator; } } m_CombinatorStack.Push(nextCombinatorType); } token = tokenizer.current; } // Step 3 : Rollback the stack of combinators and create associated expressions while (m_CombinatorStack.Count > 0) { // When a group is encountered the current expression is done var combinatorType = m_CombinatorStack.Peek(); if (combinatorType == ExpressionCombinator.Group) { m_CombinatorStack.Pop(); break; } else { ProcessCombinatorStack(); } } return(m_ExpressionStack.Pop()); }