Browse Source

- implemented correct lexing of processing instructions

- implemented correct handling of nested embedded VB blocks in XML
- implemented XmlAccessOperators

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6002 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
8588f756f9
  1. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/KeywordList.txt
  2. 107
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  3. 422
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Tokens.cs
  4. 230
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ExpressionFinder.atg
  5. 7
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ExpressionFinder.cs
  6. 3019
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Parser.cs
  7. 3
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/PushParser.frame
  8. 97
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Test/XmlModeLexerTests.cs
  9. 4520
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  10. 2
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  11. 14
      src/Libraries/NRefactory/Test/Lexer/VBNet/LexerTests.cs

2
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/KeywordList.txt

@ -41,6 +41,8 @@ ConcatString = "&" @@ -41,6 +41,8 @@ ConcatString = "&"
Div ="/"
DivInteger = "\\"
Dot = "."
TripleDot = "..."
DotAt = ".@"
# Exclamation mark = Dictionary access operator (not always a token, sometimes it's a type character)
ExclamationMark = "!"
Minus = "-"

107
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs

@ -6,10 +6,12 @@ @@ -6,10 +6,12 @@
// </file>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Parser.VBNet.Experimental;
namespace ICSharpCode.NRefactory.Parser.VB
@ -55,8 +57,20 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -55,8 +57,20 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
bool misreadExclamationMarkAsTypeCharacter;
bool inXmlMode, inXmlTag, inXmlCloseTag, wasComment;
int level = 0;
bool inXmlMode;
class XmlModeStackInfo {
public bool inXmlTag, inXmlCloseTag, wasComment, wasProcessingInstruction;
public int level;
public XmlModeStackInfo(bool isSpecial)
{
level = isSpecial ? -1 : 0;
inXmlTag = inXmlCloseTag = wasComment = wasProcessingInstruction = false;
}
}
Stack<XmlModeStackInfo> xmlModeStack = new Stack<XmlModeStackInfo>();
Token NextInternal()
{
@ -64,6 +78,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -64,6 +78,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
misreadExclamationMarkAsTypeCharacter = false;
return new Token(Tokens.ExclamationMark, Col - 1, Line);
}
unchecked {
while (true) {
Location startLocation = new Location(Col, Line);
@ -72,7 +87,8 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -72,7 +87,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(Tokens.EOF, Col, Line, string.Empty);
char ch = (char)nextChar;
#region XML mode
if (inXmlMode && level <= 0 && !wasComment) {
if (inXmlMode && xmlModeStack.Peek().level <= 0 && !xmlModeStack.Peek().wasComment && !xmlModeStack.Peek().wasProcessingInstruction && !xmlModeStack.Peek().inXmlTag) {
XmlModeStackInfo info = xmlModeStack.Peek();
int peek;
while (true) {
int step = 0;
@ -91,63 +107,60 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -91,63 +107,60 @@ namespace ICSharpCode.NRefactory.Parser.VB
break;
}
inXmlMode = false;
xmlModeStack.Pop();
}
if (inXmlMode) {
XmlModeStackInfo info = xmlModeStack.Peek();
int x = Col - 1;
int y = Line;
switch (ch) {
case '<':
if (ReaderPeek() == '/') {
ReaderRead();
inXmlCloseTag = true;
info.inXmlCloseTag = true;
return new Token(Tokens.XmlOpenEndTag, x, y);
}
if (ReaderPeek() == '%') {
// TODO : suspend xml mode tracking
ReaderRead();
if (ReaderPeek() == '%' && ReaderPeek(1) == '=') {
inXmlMode = false;
ReaderRead(); ReaderRead();
return new Token(Tokens.XmlStartInlineVB, x, y);
}
if (ReaderPeek() == '?') {
ReaderRead();
info.inXmlTag = true;
return new Token(Tokens.XmlProcessingInstructionStart, x, y);
}
if (ReaderPeek() == '!') {
ReaderRead();
Token token = ReadXmlCommentOrCData(x, y);
wasComment = token.Kind == Tokens.XmlComment;
info.wasComment = token.Kind == Tokens.XmlComment;
ReaderRead();
return token;
}
level++;
inXmlTag = true;
info.level++;
info.inXmlTag = true;
return new Token(Tokens.XmlOpenTag, x, y);
case '/':
if (ReaderPeek() == '>') {
ReaderRead();
inXmlTag = false;
level--;
info.inXmlTag = false;
info.level--;
return new Token(Tokens.XmlCloseTagEmptyElement, x, y);
}
break;
case '%':
if (ReaderPeek() == '>') {
// TODO : resume xml mode tracking
ReaderRead();
return new Token(Tokens.XmlEndInlineVB, x, y);
}
break;
case '?':
if (ReaderPeek() == '>') {
ReaderRead();
info.inXmlTag = false;
info.wasProcessingInstruction = true;
return new Token(Tokens.XmlProcessingInstructionEnd, x, y);
}
break;
case '>':
/* workaround for XML Imports */
if (inXmlCloseTag || (inXmlTag && ef.CurrentBlock.context == Context.Global))
level--;
wasComment = false;
inXmlTag = inXmlCloseTag = false;
if (info.inXmlCloseTag)
info.level--;
info.wasComment = info.wasProcessingInstruction = false;
info.inXmlTag = info.inXmlCloseTag = false;
return new Token(Tokens.XmlCloseTag, x, y);
case '=':
return new Token(Tokens.Assign, x, y);
@ -156,8 +169,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -156,8 +169,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
string s = ReadXmlString(ch);
return new Token(Tokens.LiteralString, x, y, ch + s + ch, s, LiteralFormat.StringLiteral);
default:
// TODO : can be either identifier or xml content
if (inXmlCloseTag || inXmlTag) {
if (info.inXmlCloseTag || info.inXmlTag) {
if (XmlConvert.IsWhitespaceChar(ch))
continue;
return new Token(Tokens.Identifier, x, y, ReadXmlIdent(ch));
@ -327,31 +339,44 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -327,31 +339,44 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
return new Token(Tokens.LiteralString, x, y, '"' + s + '"', s, LiteralFormat.StringLiteral);
}
if (ch == '%' && ReaderPeek() == '>') {
int x = Col - 1;
int y = Line;
inXmlMode = true;
ReaderRead();
return new Token(Tokens.XmlEndInlineVB, x, y);
}
#endregion
if (ch == '<' && ef.NextTokenIsPotentialStartOfXmlMode) {
if (ch == '<' && (ef.NextTokenIsPotentialStartOfXmlMode || ef.NextTokenIsStartOfImportsOrAccessExpression)) {
xmlModeStack.Push(new XmlModeStackInfo(ef.NextTokenIsStartOfImportsOrAccessExpression));
XmlModeStackInfo info = xmlModeStack.Peek();
int x = Col - 1;
int y = Line;
inXmlMode = true;
level = 0;
if (ReaderPeek() == '/') {
ReaderRead();
inXmlCloseTag = true;
info.inXmlCloseTag = true;
return new Token(Tokens.XmlOpenEndTag, x, y);
}
if (ReaderPeek() == '%') {
if (ReaderPeek() == '%' && ReaderPeek(1) == '=') {
// TODO : suspend xml mode tracking
ReaderRead();
ReaderRead(); ReaderRead();
return new Token(Tokens.XmlStartInlineVB, x, y);
}
if (ReaderPeek() == '!') {
ReaderRead();
Token t = ReadXmlCommentOrCData(x, y);
wasComment = t.Kind == Tokens.XmlComment;
info.wasComment = t.Kind == Tokens.XmlComment;
ReaderRead();
return t;
}
inXmlTag = true;
level = 1;
if (ReaderPeek() == '?') {
ReaderRead();
info.inXmlTag = true;
return new Token(Tokens.XmlProcessingInstructionStart, x, y);
}
info.inXmlTag = true;
info.level++;
return new Token(Tokens.XmlOpenTag, x, y);
}
Token token = ReadOperator(ch);
@ -960,9 +985,17 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -960,9 +985,17 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(Tokens.Comma, x, y);
case '.':
// Prevent OverflowException when Peek returns -1
int tmp = ReaderPeek();
if (tmp > 0 && Char.IsDigit((char)tmp)) {
return ReadDigit('.', Col);
int tmp = ReaderPeek(); int tmp2 = ReaderPeek(1);
if (tmp > 0) {
if (char.IsDigit((char)tmp))
return ReadDigit('.', Col);
else if ((char)tmp == '@') {
ReaderRead();
return new Token(Tokens.DotAt, x, y);
} else if ((char)tmp == '.' && tmp2 > 0 && (char)tmp2 == '.') {
ReaderRead(); ReaderRead();
return new Token(Tokens.TripleDot, x, y);
}
}
return new Token(Tokens.Dot, x, y);
case '(':

422
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Tokens.cs

@ -37,218 +37,220 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -37,218 +37,220 @@ namespace ICSharpCode.NRefactory.Parser.VB
public const int Div = 25;
public const int DivInteger = 26;
public const int Dot = 27;
public const int ExclamationMark = 28;
public const int Minus = 29;
public const int Plus = 30;
public const int Power = 31;
public const int QuestionMark = 32;
public const int Times = 33;
public const int OpenCurlyBrace = 34;
public const int CloseCurlyBrace = 35;
public const int OpenParenthesis = 36;
public const int CloseParenthesis = 37;
public const int GreaterThan = 38;
public const int LessThan = 39;
public const int NotEqual = 40;
public const int GreaterEqual = 41;
public const int LessEqual = 42;
public const int ShiftLeft = 43;
public const int ShiftRight = 44;
public const int PlusAssign = 45;
public const int PowerAssign = 46;
public const int MinusAssign = 47;
public const int TimesAssign = 48;
public const int DivAssign = 49;
public const int DivIntegerAssign = 50;
public const int ShiftLeftAssign = 51;
public const int ShiftRightAssign = 52;
public const int ConcatStringAssign = 53;
public const int ColonAssign = 54;
public const int TripleDot = 28;
public const int DotAt = 29;
public const int ExclamationMark = 30;
public const int Minus = 31;
public const int Plus = 32;
public const int Power = 33;
public const int QuestionMark = 34;
public const int Times = 35;
public const int OpenCurlyBrace = 36;
public const int CloseCurlyBrace = 37;
public const int OpenParenthesis = 38;
public const int CloseParenthesis = 39;
public const int GreaterThan = 40;
public const int LessThan = 41;
public const int NotEqual = 42;
public const int GreaterEqual = 43;
public const int LessEqual = 44;
public const int ShiftLeft = 45;
public const int ShiftRight = 46;
public const int PlusAssign = 47;
public const int PowerAssign = 48;
public const int MinusAssign = 49;
public const int TimesAssign = 50;
public const int DivAssign = 51;
public const int DivIntegerAssign = 52;
public const int ShiftLeftAssign = 53;
public const int ShiftRightAssign = 54;
public const int ConcatStringAssign = 55;
public const int ColonAssign = 56;
// ----- keywords -----
public const int AddHandler = 55;
public const int AddressOf = 56;
public const int Aggregate = 57;
public const int Alias = 58;
public const int And = 59;
public const int AndAlso = 60;
public const int Ansi = 61;
public const int As = 62;
public const int Ascending = 63;
public const int Assembly = 64;
public const int Auto = 65;
public const int Binary = 66;
public const int Boolean = 67;
public const int ByRef = 68;
public const int By = 69;
public const int Byte = 70;
public const int ByVal = 71;
public const int Call = 72;
public const int Case = 73;
public const int Catch = 74;
public const int CBool = 75;
public const int CByte = 76;
public const int CChar = 77;
public const int CDate = 78;
public const int CDbl = 79;
public const int CDec = 80;
public const int Char = 81;
public const int CInt = 82;
public const int Class = 83;
public const int CLng = 84;
public const int CObj = 85;
public const int Compare = 86;
public const int Const = 87;
public const int Continue = 88;
public const int CSByte = 89;
public const int CShort = 90;
public const int CSng = 91;
public const int CStr = 92;
public const int CType = 93;
public const int CUInt = 94;
public const int CULng = 95;
public const int CUShort = 96;
public const int Custom = 97;
public const int Date = 98;
public const int Decimal = 99;
public const int Declare = 100;
public const int Default = 101;
public const int Delegate = 102;
public const int Descending = 103;
public const int Dim = 104;
public const int DirectCast = 105;
public const int Distinct = 106;
public const int Do = 107;
public const int Double = 108;
public const int Each = 109;
public const int Else = 110;
public const int ElseIf = 111;
public const int End = 112;
public const int EndIf = 113;
public const int Enum = 114;
new public const int Equals = 115;
public const int Erase = 116;
public const int Error = 117;
public const int Event = 118;
public const int Exit = 119;
public const int Explicit = 120;
public const int False = 121;
public const int Finally = 122;
public const int For = 123;
public const int Friend = 124;
public const int From = 125;
public const int Function = 126;
public const int Get = 127;
new public const int GetType = 128;
public const int Global = 129;
public const int GoSub = 130;
public const int GoTo = 131;
public const int Group = 132;
public const int Handles = 133;
public const int If = 134;
public const int Implements = 135;
public const int Imports = 136;
public const int In = 137;
public const int Infer = 138;
public const int Inherits = 139;
public const int Integer = 140;
public const int Interface = 141;
public const int Into = 142;
public const int Is = 143;
public const int IsNot = 144;
public const int Join = 145;
public const int Key = 146;
public const int Let = 147;
public const int Lib = 148;
public const int Like = 149;
public const int Long = 150;
public const int Loop = 151;
public const int Me = 152;
public const int Mod = 153;
public const int Module = 154;
public const int MustInherit = 155;
public const int MustOverride = 156;
public const int MyBase = 157;
public const int MyClass = 158;
public const int Namespace = 159;
public const int Narrowing = 160;
public const int New = 161;
public const int Next = 162;
public const int Not = 163;
public const int Nothing = 164;
public const int NotInheritable = 165;
public const int NotOverridable = 166;
public const int Object = 167;
public const int Of = 168;
public const int Off = 169;
public const int On = 170;
public const int Operator = 171;
public const int Option = 172;
public const int Optional = 173;
public const int Or = 174;
public const int Order = 175;
public const int OrElse = 176;
public const int Overloads = 177;
public const int Overridable = 178;
public const int Overrides = 179;
public const int ParamArray = 180;
public const int Partial = 181;
public const int Preserve = 182;
public const int Private = 183;
public const int Property = 184;
public const int Protected = 185;
public const int Public = 186;
public const int RaiseEvent = 187;
public const int ReadOnly = 188;
public const int ReDim = 189;
public const int Rem = 190;
public const int RemoveHandler = 191;
public const int Resume = 192;
public const int Return = 193;
public const int SByte = 194;
public const int Select = 195;
public const int Set = 196;
public const int Shadows = 197;
public const int Shared = 198;
public const int Short = 199;
public const int Single = 200;
public const int Skip = 201;
public const int Static = 202;
public const int Step = 203;
public const int Stop = 204;
public const int Strict = 205;
public const int String = 206;
public const int Structure = 207;
public const int Sub = 208;
public const int SyncLock = 209;
public const int Take = 210;
public const int Text = 211;
public const int Then = 212;
public const int Throw = 213;
public const int To = 214;
public const int True = 215;
public const int Try = 216;
public const int TryCast = 217;
public const int TypeOf = 218;
public const int UInteger = 219;
public const int ULong = 220;
public const int Unicode = 221;
public const int Until = 222;
public const int UShort = 223;
public const int Using = 224;
public const int Variant = 225;
public const int Wend = 226;
public const int When = 227;
public const int Where = 228;
public const int While = 229;
public const int Widening = 230;
public const int With = 231;
public const int WithEvents = 232;
public const int WriteOnly = 233;
public const int Xor = 234;
public const int GetXmlNamespace = 235;
public const int AddHandler = 57;
public const int AddressOf = 58;
public const int Aggregate = 59;
public const int Alias = 60;
public const int And = 61;
public const int AndAlso = 62;
public const int Ansi = 63;
public const int As = 64;
public const int Ascending = 65;
public const int Assembly = 66;
public const int Auto = 67;
public const int Binary = 68;
public const int Boolean = 69;
public const int ByRef = 70;
public const int By = 71;
public const int Byte = 72;
public const int ByVal = 73;
public const int Call = 74;
public const int Case = 75;
public const int Catch = 76;
public const int CBool = 77;
public const int CByte = 78;
public const int CChar = 79;
public const int CDate = 80;
public const int CDbl = 81;
public const int CDec = 82;
public const int Char = 83;
public const int CInt = 84;
public const int Class = 85;
public const int CLng = 86;
public const int CObj = 87;
public const int Compare = 88;
public const int Const = 89;
public const int Continue = 90;
public const int CSByte = 91;
public const int CShort = 92;
public const int CSng = 93;
public const int CStr = 94;
public const int CType = 95;
public const int CUInt = 96;
public const int CULng = 97;
public const int CUShort = 98;
public const int Custom = 99;
public const int Date = 100;
public const int Decimal = 101;
public const int Declare = 102;
public const int Default = 103;
public const int Delegate = 104;
public const int Descending = 105;
public const int Dim = 106;
public const int DirectCast = 107;
public const int Distinct = 108;
public const int Do = 109;
public const int Double = 110;
public const int Each = 111;
public const int Else = 112;
public const int ElseIf = 113;
public const int End = 114;
public const int EndIf = 115;
public const int Enum = 116;
new public const int Equals = 117;
public const int Erase = 118;
public const int Error = 119;
public const int Event = 120;
public const int Exit = 121;
public const int Explicit = 122;
public const int False = 123;
public const int Finally = 124;
public const int For = 125;
public const int Friend = 126;
public const int From = 127;
public const int Function = 128;
public const int Get = 129;
new public const int GetType = 130;
public const int Global = 131;
public const int GoSub = 132;
public const int GoTo = 133;
public const int Group = 134;
public const int Handles = 135;
public const int If = 136;
public const int Implements = 137;
public const int Imports = 138;
public const int In = 139;
public const int Infer = 140;
public const int Inherits = 141;
public const int Integer = 142;
public const int Interface = 143;
public const int Into = 144;
public const int Is = 145;
public const int IsNot = 146;
public const int Join = 147;
public const int Key = 148;
public const int Let = 149;
public const int Lib = 150;
public const int Like = 151;
public const int Long = 152;
public const int Loop = 153;
public const int Me = 154;
public const int Mod = 155;
public const int Module = 156;
public const int MustInherit = 157;
public const int MustOverride = 158;
public const int MyBase = 159;
public const int MyClass = 160;
public const int Namespace = 161;
public const int Narrowing = 162;
public const int New = 163;
public const int Next = 164;
public const int Not = 165;
public const int Nothing = 166;
public const int NotInheritable = 167;
public const int NotOverridable = 168;
public const int Object = 169;
public const int Of = 170;
public const int Off = 171;
public const int On = 172;
public const int Operator = 173;
public const int Option = 174;
public const int Optional = 175;
public const int Or = 176;
public const int Order = 177;
public const int OrElse = 178;
public const int Overloads = 179;
public const int Overridable = 180;
public const int Overrides = 181;
public const int ParamArray = 182;
public const int Partial = 183;
public const int Preserve = 184;
public const int Private = 185;
public const int Property = 186;
public const int Protected = 187;
public const int Public = 188;
public const int RaiseEvent = 189;
public const int ReadOnly = 190;
public const int ReDim = 191;
public const int Rem = 192;
public const int RemoveHandler = 193;
public const int Resume = 194;
public const int Return = 195;
public const int SByte = 196;
public const int Select = 197;
public const int Set = 198;
public const int Shadows = 199;
public const int Shared = 200;
public const int Short = 201;
public const int Single = 202;
public const int Skip = 203;
public const int Static = 204;
public const int Step = 205;
public const int Stop = 206;
public const int Strict = 207;
public const int String = 208;
public const int Structure = 209;
public const int Sub = 210;
public const int SyncLock = 211;
public const int Take = 212;
public const int Text = 213;
public const int Then = 214;
public const int Throw = 215;
public const int To = 216;
public const int True = 217;
public const int Try = 218;
public const int TryCast = 219;
public const int TypeOf = 220;
public const int UInteger = 221;
public const int ULong = 222;
public const int Unicode = 223;
public const int Until = 224;
public const int UShort = 225;
public const int Using = 226;
public const int Variant = 227;
public const int Wend = 228;
public const int When = 229;
public const int Where = 230;
public const int While = 231;
public const int Widening = 232;
public const int With = 233;
public const int WithEvents = 234;
public const int WriteOnly = 235;
public const int Xor = 236;
public const int GetXmlNamespace = 237;
public const int MaxToken = 236;
public const int MaxToken = 238;
static BitArray NewSet(params int[] values)
{
BitArray bitArray = new BitArray(MaxToken);
@ -297,6 +299,8 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -297,6 +299,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
"/",
"\\",
".",
"...",
".@",
"!",
"-",
"+",

230
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ExpressionFinder.atg

@ -42,6 +42,8 @@ TOKENS @@ -42,6 +42,8 @@ TOKENS
"/"
"\\"
"."
"..."
".@"
"!"
"-"
"+"
@ -274,7 +276,7 @@ OptionStatement = @@ -274,7 +276,7 @@ OptionStatement =
.
ImportsStatement =
"Imports" (. nextTokenIsPotentialStartOfXmlMode = true; .) { ANY } StatementTerminator
"Imports" (. nextTokenIsStartOfImportsOrAccessExpression = true; .) { ANY } StatementTerminator
.
AttributeBlock =
@ -282,8 +284,8 @@ AttributeBlock = @@ -282,8 +284,8 @@ AttributeBlock =
.
NamespaceMemberDeclaration =
NamespaceDeclaration |
TypeDeclaration
NamespaceDeclaration
| TypeDeclaration
.
NamespaceDeclaration =
@ -388,7 +390,12 @@ StatementTerminatorAndBlock = @@ -388,7 +390,12 @@ StatementTerminatorAndBlock =
(. PopContext(); .)
.
Expression =
Expression
(.
if (la != null)
CurrentBlock.lastExpressionStart = la.Location;
.)
=
SimpleExpressionWithSuffix { BinaryOperator SimpleExpressionWithSuffix }
.
@ -467,7 +474,7 @@ CollectionInitializer = @@ -467,7 +474,7 @@ CollectionInitializer =
ExpressionSuffix =
"(" ( "Of" TypeName { "," TypeName } ")" | ArgumentList ")" )
| ( "." | "!" ) IdentifierOrKeyword
| ( "." | "!" | ".@" | "..." ) (. nextTokenIsStartOfImportsOrAccessExpression = true; .) [ XmlOpenTag ] IdentifierOrKeyword [ XmlCloseTag ]
.
CastExpression =
@ -621,12 +628,20 @@ XmlLiteral @@ -621,12 +628,20 @@ XmlLiteral
(.OnEachPossiblePath: nextTokenIsPotentialStartOfXmlMode = true; .)
=
(. PushContext(Context.Xml, t); .)
{ XmlComment } XmlElement { XmlComment }
{ XmlComment [ XmlContent ] | XmlProcessingInstruction [ XmlContent ] } XmlElement { XmlComment [ XmlContent ] }
(. PopContext(); .)
.
XmlElement =
XmlOpenTag { ANY } ( XmlCloseTagEmptyElement | XmlCloseTag { ANY | XmlElement } XmlOpenEndTag { ANY } XmlCloseTag )
XmlOpenTag { ANY | XmlEmbeddedExpression } ( XmlCloseTagEmptyElement | XmlCloseTag { ANY | XmlEmbeddedExpression | XmlElement } XmlOpenEndTag { ANY | XmlEmbeddedExpression } XmlCloseTag )
.
XmlProcessingInstruction =
XmlProcessingInstructionStart Identifier { Identifier [ "=" LiteralString ] } XmlProcessingInstructionEnd
.
XmlEmbeddedExpression =
XmlStartInlineVB Expression XmlEndInlineVB
.
PrimitiveTypeName =
@ -652,7 +667,189 @@ TypeName = ( "Global" | Identifier | PrimitiveTypeName ) { TypeSuffix } { "." Id @@ -652,7 +667,189 @@ TypeName = ( "Global" | Identifier | PrimitiveTypeName ) { TypeSuffix } { "." Id
TypeSuffix = "(" ( "Of" [ TypeName ] { "," [ TypeName ] } | [ ArgumentList ] ) ")" .
IdentifierOrKeyword = ANY .
IdentifierOrKeyword = ident
| "AddHandler"
| "AddressOf"
| "Aggregate"
| "Alias"
| "And"
| "AndAlso"
| "Ansi"
| "As"
| "Ascending"
| "Assembly"
| "Auto"
| "Binary"
| "Boolean"
| "ByRef"
| "By"
| "Byte"
| "ByVal"
| "Call"
| "Case"
| "Catch"
| "CBool"
| "CByte"
| "CChar"
| "CDate"
| "CDbl"
| "CDec"
| "Char"
| "CInt"
| "Class"
| "CLng"
| "CObj"
| "Compare"
| "Const"
| "Continue"
| "CSByte"
| "CShort"
| "CSng"
| "CStr"
| "CType"
| "CUInt"
| "CULng"
| "CUShort"
| "Custom"
| "Date"
| "Decimal"
| "Declare"
| "Default"
| "Delegate"
| "Descending"
| "Dim"
| "DirectCast"
| "Distinct"
| "Do"
| "Double"
| "Each"
| "Else"
| "ElseIf"
| "End"
| "EndIf"
| "Enum"
| "Equals"
| "Erase"
| "Error"
| "Event"
| "Exit"
| "Explicit"
| "False"
| "Finally"
| "For"
| "Friend"
| "From"
| "Function"
| "Get"
| "GetType"
| "Global"
| "GoSub"
| "GoTo"
| "Group"
| "Handles"
| "If"
| "Implements"
| "Imports"
| "In"
| "Infer"
| "Inherits"
| "Integer"
| "Interface"
| "Into"
| "Is"
| "IsNot"
| "Join"
| "Key"
| "Let"
| "Lib"
| "Like"
| "Long"
| "Loop"
| "Me"
| "Mod"
| "Module"
| "MustInherit"
| "MustOverride"
| "MyBase"
| "MyClass"
| "Namespace"
| "Narrowing"
| "New"
| "Next"
| "Not"
| "Nothing"
| "NotInheritable"
| "NotOverridable"
| "Object"
| "Of"
| "Off"
| "On"
| "Operator"
| "Option"
| "Optional"
| "Or"
| "Order"
| "OrElse"
| "Overloads"
| "Overridable"
| "Overrides"
| "ParamArray"
| "Partial"
| "Preserve"
| "Private"
| "Property"
| "Protected"
| "Public"
| "RaiseEvent"
| "ReadOnly"
| "ReDim"
| "Rem"
| "RemoveHandler"
| "Resume"
| "Return"
| "SByte"
| "Select"
| "Set"
| "Shadows"
| "Shared"
| "Short"
| "Single"
| "Skip"
| "Static"
| "Step"
| "Stop"
| "Strict"
| "String"
| "Structure"
| "Sub"
| "SyncLock"
| "Take"
| "Text"
| "Then"
| "Throw"
| "To"
| "True"
| "Try"
| "TryCast"
| "TypeOf"
| "UInteger"
| "ULong"
| "Unicode"
| "Until"
| "UShort"
| "Using"
| "Variant"
| "Wend"
| "When"
| "Where"
| "While"
| "Widening"
| "With"
| "WithEvents"
| "WriteOnly"
| "Xor"
| "GetXmlNamespace"
.
Literal =
LiteralString |
@ -671,7 +868,12 @@ Literal = @@ -671,7 +868,12 @@ Literal =
"MyClass"
.
Statement =
Statement
(.
if (la != null)
CurrentBlock.lastExpressionStart = la.Location;
.)
=
VariableDeclarationStatement
| WithOrLockStatement
| AddOrRemoveHandlerStatement
@ -692,7 +894,13 @@ Statement = @@ -692,7 +894,13 @@ Statement =
.
VariableDeclarationStatement =
( "Dim" | "Static" | "Const" ) (. PushContext(Context.IdentifierExpected, t); .) Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ] { "," (. PushContext(Context.IdentifierExpected, t); .) Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ] } [ "As" [ "New" ] TypeName ] [ "=" Expression ]
( "Dim" | "Static" | "Const" )
(.
PushContext(Context.IdentifierExpected, t);
if (la != null)
CurrentBlock.lastExpressionStart = la.Location;
.)
Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ] { "," (. PushContext(Context.IdentifierExpected, t); .) Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ] } [ "As" [ "New" ] TypeName ] [ "=" Expression ]
.
WithOrLockStatement =
@ -849,7 +1057,7 @@ Identifier = @@ -849,7 +1057,7 @@ Identifier =
| "Custom"
.
IdentifierForFieldDeclaration =
IdentifierForFieldDeclaration =
IdentifierForExpressionStart
| "Aggregate"
| "From"

7
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ExpressionFinder.cs

@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.Parser.VBNet.Experimental @@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.Parser.VBNet.Experimental
void ApplyToken(Token token)
{
Console.WriteLine(token);
//Console.WriteLine(token);
if (stack.Count == 0 || token == null)
return;
@ -97,6 +97,11 @@ namespace ICSharpCode.NRefactory.Parser.VBNet.Experimental @@ -97,6 +97,11 @@ namespace ICSharpCode.NRefactory.Parser.VBNet.Experimental
get { return readXmlIdentifier; }
set { readXmlIdentifier = value; }
}
public bool NextTokenIsStartOfImportsOrAccessExpression {
get { return nextTokenIsStartOfImportsOrAccessExpression; }
set { nextTokenIsStartOfImportsOrAccessExpression = value; }
}
}
public enum Context

3019
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Parser.cs

File diff suppressed because it is too large Load Diff

3
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/PushParser.frame

@ -36,6 +36,7 @@ partial class ExpressionFinder { @@ -36,6 +36,7 @@ partial class ExpressionFinder {
readonly Stack<int> stateStack = new Stack<int>();
bool nextTokenIsPotentialStartOfXmlMode = false;
bool readXmlIdentifier = false;
bool nextTokenIsStartOfImportsOrAccessExpression = false;
public ExpressionFinder()
{
@ -59,6 +60,8 @@ partial class ExpressionFinder { @@ -59,6 +60,8 @@ partial class ExpressionFinder {
public void InformToken(Token la)
{
nextTokenIsPotentialStartOfXmlMode = false;
readXmlIdentifier = false;
nextTokenIsStartOfImportsOrAccessExpression = false;
-->informToken
ApplyToken(la);
if (la != null) t = la;

97
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Test/XmlModeLexerTests.cs

@ -326,6 +326,87 @@ namespace DefaultNamespace @@ -326,6 +326,87 @@ namespace DefaultNamespace
CheckFoot(lexer);
}
[Test]
public void InlineVB()
{
string code = @"Dim xml = <?xml version='1.0'?>
<menu>
<course name=""appetizer"">
<%= From m In menu _
Where m.Course = ""appetizer"" _
Select <dish><%= m.Food %></dish> _
%>
</course>
<course name=""main"">
<%= From m In menu _
Where m.Course = ""main"" _
Select <dish><%= m.Food %></dish> _
%>
</course>
<course name=""dessert"">
<%= From m In menu _
Where m.Course = ""dessert"" _
Select <dish><%= m.Food %></dish> _
%>
</course>
</menu>";
ILexer lexer = GenerateLexer(new StringReader(TestStatement(code)));
CheckHead(lexer);
CheckTokens(lexer, Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.XmlProcessingInstructionStart, Tokens.Identifier,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.XmlProcessingInstructionEnd, Tokens.XmlContent,
Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlOpenTag, Tokens.Identifier,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlStartInlineVB,
Tokens.From, Tokens.Identifier, Tokens.In, Tokens.Identifier, Tokens.Where, Tokens.Identifier, Tokens.Dot,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.Select, Tokens.XmlOpenTag, Tokens.Identifier,
Tokens.XmlCloseTag, Tokens.XmlStartInlineVB, Tokens.Identifier, Tokens.Dot, Tokens.Identifier, Tokens.XmlEndInlineVB,
Tokens.XmlOpenEndTag, Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlEndInlineVB, Tokens.XmlContent, Tokens.XmlOpenEndTag,
Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlOpenTag, Tokens.Identifier,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlStartInlineVB,
Tokens.From, Tokens.Identifier, Tokens.In, Tokens.Identifier, Tokens.Where, Tokens.Identifier, Tokens.Dot,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.Select, Tokens.XmlOpenTag, Tokens.Identifier,
Tokens.XmlCloseTag, Tokens.XmlStartInlineVB, Tokens.Identifier, Tokens.Dot, Tokens.Identifier, Tokens.XmlEndInlineVB,
Tokens.XmlOpenEndTag, Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlEndInlineVB, Tokens.XmlContent, Tokens.XmlOpenEndTag,
Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlOpenTag, Tokens.Identifier,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlStartInlineVB,
Tokens.From, Tokens.Identifier, Tokens.In, Tokens.Identifier, Tokens.Where, Tokens.Identifier, Tokens.Dot,
Tokens.Identifier, Tokens.Assign, Tokens.LiteralString, Tokens.Select, Tokens.XmlOpenTag, Tokens.Identifier,
Tokens.XmlCloseTag, Tokens.XmlStartInlineVB, Tokens.Identifier, Tokens.Dot, Tokens.Identifier, Tokens.XmlEndInlineVB,
Tokens.XmlOpenEndTag, Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlEndInlineVB, Tokens.XmlContent, Tokens.XmlOpenEndTag,
Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlOpenEndTag, Tokens.Identifier, Tokens.XmlCloseTag
);
CheckFoot(lexer);
}
[Test]
public void XmlAccessOperators()
{
string code = @"Dim childAxis = xml.<menu>.<course>
Dim course3 = xml...<course>(2)
Dim childAxis = xml...<course>
For Each item In childAxis
Console.WriteLine(item.@name)
Next";
ILexer lexer = GenerateLexer(new StringReader(TestStatement(code)));
CheckHead(lexer);
CheckTokens(lexer, Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.Identifier, Tokens.Dot, Tokens.XmlOpenTag,
Tokens.Identifier, Tokens.XmlCloseTag, Tokens.Dot, Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTag,
Tokens.EOL, Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.Identifier, Tokens.TripleDot, Tokens.XmlOpenTag,
Tokens.Identifier, Tokens.XmlCloseTag, Tokens.OpenParenthesis, Tokens.LiteralInteger, Tokens.CloseParenthesis,
Tokens.EOL, Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.Identifier, Tokens.TripleDot, Tokens.XmlOpenTag,
Tokens.Identifier, Tokens.XmlCloseTag, Tokens.EOL, Tokens.For, Tokens.Each, Tokens.Identifier, Tokens.In, Tokens.Identifier, Tokens.EOL,
Tokens.Identifier, Tokens.Dot, Tokens.Identifier, Tokens.OpenParenthesis, Tokens.Identifier, Tokens.DotAt, Tokens.Identifier, Tokens.CloseParenthesis, Tokens.EOL,
Tokens.Next);
CheckFoot(lexer);
}
[Test]
public void GetXmlNamespace()
{
@ -336,7 +417,6 @@ namespace DefaultNamespace @@ -336,7 +417,6 @@ namespace DefaultNamespace
CheckTokens(lexer, Tokens.Dim, Tokens.Identifier, Tokens.Assign,
Tokens.GetXmlNamespace, Tokens.OpenParenthesis, Tokens.Identifier, Tokens.CloseParenthesis);
CheckFoot(lexer);
}
@ -354,6 +434,21 @@ namespace DefaultNamespace @@ -354,6 +434,21 @@ namespace DefaultNamespace
CheckFoot(lexer);
}
[Test]
public void XmlInSelect()
{
ILexer lexer = GenerateLexer(new StringReader(TestStatement("Dim data = From x In list Select <test>x</test>")));
CheckHead(lexer);
CheckTokens(lexer, Tokens.Dim, Tokens.Identifier, Tokens.Assign,
Tokens.From, Tokens.Identifier, Tokens.In, Tokens.Identifier, Tokens.Select,
Tokens.XmlOpenTag, Tokens.Identifier, Tokens.XmlCloseTag, Tokens.XmlContent, Tokens.XmlOpenEndTag,
Tokens.Identifier, Tokens.XmlCloseTag);
CheckFoot(lexer);
}
[Test]
public void IfExpressionTest()
{

4520
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

2
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG

@ -41,6 +41,8 @@ TOKENS @@ -41,6 +41,8 @@ TOKENS
"/"
"\\"
"."
"..."
".@"
"!"
"-"
"+"

14
src/Libraries/NRefactory/Test/Lexer/VBNet/LexerTests.cs

@ -65,6 +65,20 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB @@ -65,6 +65,20 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
Assert.AreEqual(Tokens.Dot, lexer.NextToken().Kind);
}
[Test]
public void TestTripleDot()
{
ILexer lexer = GenerateLexer(new StringReader("..."));
Assert.AreEqual(Tokens.TripleDot, lexer.NextToken().Kind);
}
[Test]
public void TestDotAt()
{
ILexer lexer = GenerateLexer(new StringReader(".@"));
Assert.AreEqual(Tokens.DotAt, lexer.NextToken().Kind);
}
[Test]
public void TestExclamationMark()
{

Loading…
Cancel
Save