private void Attrib() { //attrib // : '[' S* [ namespace_prefix ]? IDENT S* // [ [ PREFIXMATCH | // SUFFIXMATCH | // SUBSTRINGMATCH | // '=' | // INCLUDES | // DASHMATCH ] S* [ IDENT | STRING ] S* // ]? ']' // ; Read(ToTokenSpec(Token.LeftBracket())); var prefix = TryNamespacePrefix() ?? NamespacePrefix.None; var name = Read(ToTokenSpec(TokenKind.Ident)).Text; var hasValue = false; while (true) { var op = TryRead( ToTokenSpec(Token.Equals()), ToTokenSpec(TokenKind.NotEqual), ToTokenSpec(TokenKind.Includes), ToTokenSpec(TokenKind.RegexMatch), ToTokenSpec(TokenKind.DashMatch), ToTokenSpec(TokenKind.PrefixMatch), ToTokenSpec(TokenKind.SuffixMatch), ToTokenSpec(TokenKind.SubstringMatch)); if (op == null) { break; } hasValue = true; var value = Read(ToTokenSpec(TokenKind.String), ToTokenSpec(TokenKind.Ident)).Text; if (op.Value == Token.Equals()) { _generator.AttributeExact(prefix, name, value); } else { switch (op.Value.Kind) { case TokenKind.Includes: _generator.AttributeIncludes(prefix, name, value); break; case TokenKind.RegexMatch: _generator.AttributeRegexMatch(prefix, name, value); break; case TokenKind.DashMatch: _generator.AttributeDashMatch(prefix, name, value); break; case TokenKind.PrefixMatch: _generator.AttributePrefixMatch(prefix, name, value); break; case TokenKind.SuffixMatch: _generator.AttributeSuffixMatch(prefix, name, value); break; case TokenKind.SubstringMatch: _generator.AttributeSubstring(prefix, name, value); break; case TokenKind.NotEqual: _generator.AttributeNotEqual(prefix, name, value); break; } } } if (!hasValue) { _generator.AttributeExists(prefix, name); } Read(ToTokenSpec(Token.RightBracket())); }