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 = "&"
Div ="/" Div ="/"
DivInteger = "\\" DivInteger = "\\"
Dot = "." Dot = "."
TripleDot = "..."
DotAt = ".@"
# Exclamation mark = Dictionary access operator (not always a token, sometimes it's a type character) # Exclamation mark = Dictionary access operator (not always a token, sometimes it's a type character)
ExclamationMark = "!" ExclamationMark = "!"
Minus = "-" Minus = "-"

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

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

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

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

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

@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.Parser.VBNet.Experimental
void ApplyToken(Token token) void ApplyToken(Token token)
{ {
Console.WriteLine(token); //Console.WriteLine(token);
if (stack.Count == 0 || token == null) if (stack.Count == 0 || token == null)
return; return;
@ -97,6 +97,11 @@ namespace ICSharpCode.NRefactory.Parser.VBNet.Experimental
get { return readXmlIdentifier; } get { return readXmlIdentifier; }
set { readXmlIdentifier = value; } set { readXmlIdentifier = value; }
} }
public bool NextTokenIsStartOfImportsOrAccessExpression {
get { return nextTokenIsStartOfImportsOrAccessExpression; }
set { nextTokenIsStartOfImportsOrAccessExpression = value; }
}
} }
public enum Context 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 {
readonly Stack<int> stateStack = new Stack<int>(); readonly Stack<int> stateStack = new Stack<int>();
bool nextTokenIsPotentialStartOfXmlMode = false; bool nextTokenIsPotentialStartOfXmlMode = false;
bool readXmlIdentifier = false; bool readXmlIdentifier = false;
bool nextTokenIsStartOfImportsOrAccessExpression = false;
public ExpressionFinder() public ExpressionFinder()
{ {
@ -59,6 +60,8 @@ partial class ExpressionFinder {
public void InformToken(Token la) public void InformToken(Token la)
{ {
nextTokenIsPotentialStartOfXmlMode = false; nextTokenIsPotentialStartOfXmlMode = false;
readXmlIdentifier = false;
nextTokenIsStartOfImportsOrAccessExpression = false;
-->informToken -->informToken
ApplyToken(la); ApplyToken(la);
if (la != null) t = la; if (la != null) t = la;

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

@ -326,6 +326,87 @@ namespace DefaultNamespace
CheckFoot(lexer); 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] [Test]
public void GetXmlNamespace() public void GetXmlNamespace()
{ {
@ -336,7 +417,6 @@ namespace DefaultNamespace
CheckTokens(lexer, Tokens.Dim, Tokens.Identifier, Tokens.Assign, CheckTokens(lexer, Tokens.Dim, Tokens.Identifier, Tokens.Assign,
Tokens.GetXmlNamespace, Tokens.OpenParenthesis, Tokens.Identifier, Tokens.CloseParenthesis); Tokens.GetXmlNamespace, Tokens.OpenParenthesis, Tokens.Identifier, Tokens.CloseParenthesis);
CheckFoot(lexer); CheckFoot(lexer);
} }
@ -354,6 +434,21 @@ namespace DefaultNamespace
CheckFoot(lexer); 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] [Test]
public void IfExpressionTest() 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
"/" "/"
"\\" "\\"
"." "."
"..."
".@"
"!" "!"
"-" "-"
"+" "+"

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

@ -65,6 +65,20 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
Assert.AreEqual(Tokens.Dot, lexer.NextToken().Kind); 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] [Test]
public void TestExclamationMark() public void TestExclamationMark()
{ {

Loading…
Cancel
Save