读书人

使用正则表达式实现语法分析讨论与完

发布时间: 2012-02-28 13:06:35 作者: rapoo

使用正则表达式实现语法分析,讨论与完善
昨天有人问怎么用RichTextBox做语法高亮
这就需要用到语法分析
还有很多论坛里也支持语法高亮的功能、代码折叠的功能
这也算是一个常用的功能
所以就随手搭建一个语法分析的框架
思路是利用正则表达式逐步取得各种语法构成部分

这里欢迎大家测试、找BUG、完善正则表达式
谢谢参与


初步代码如下:
/// <summary>
/// 语法分析引擎基类
/// </summary>
class SyntaxEngine
{
/// <summary>
/// 语法项
/// </summary>
public class SyntaxItem
{
#region 私有字段
private string FPattern; // 正则表达式
private RegexOptions FOptions; // 正则表达式附加选项
private string FName; // 语法名称
private int FIndex; // 序号
#endregion 私有字段

#region 公有属性
public string Pattern { get { return FPattern; } } // 正则表达式
public RegexOptions Options { get { return FOptions; } } // 正则表达式附加选项
public string Name { get { return FName; } } // 名称
public int Index { get { return FIndex; } } // 序号
#endregion 公有属性

public SyntaxItem(string APattern, RegexOptions AOptions,
string AName, int AIndex)
{
FPattern = APattern;
FOptions = AOptions;
FName = AName;
FIndex = AIndex;
}
}
/// <summary>
/// 语法分析返回项
/// </summary>
public class AnalyzeReslut
{
#region 私有字段
private SyntaxItem FItem; // 所属语法项
private string FBlock; // 文字块


#endregion 私有字段

#region 公有属性
public SyntaxItem Item { get { return FItem; } }
public string Block { get { return FBlock; } }
#endregion 公有属性

public AnalyzeReslut(SyntaxItem AItem, string ABlock)
{
FItem = AItem;
FBlock = ABlock;
}
}

private List <SyntaxItem> FSyntaxItems = new List <SyntaxItem> ();
private List <AnalyzeReslut> FAnalyzeResluts = new List <AnalyzeReslut> ();

public List <SyntaxItem> SyntaxItems { get { return FSyntaxItems; } }
public List <AnalyzeReslut> AnalyzeResluts { get { return FAnalyzeResluts; } }

/// <summary>
/// 进行语法分析
/// </summary>
/// <param name= "ACode "> 所分析的代码 </param>
/// <returns> 返回分析是否成功 </returns>
public virtual bool Analyze(string ACode)
{
if (FSyntaxItems.Count <= 0) return false;
if (ACode == null) return false;
AnalyzeResluts.Clear();
string vCode = ACode;
bool vFind = true;
while (vFind && (vCode.Length > 0))
{
vFind = false;
foreach (SyntaxItem vSyntaxItem in FSyntaxItems)
{
if (Regex.IsMatch(vCode, vSyntaxItem.Pattern, vSyntaxItem.Options))
{


AnalyzeResluts.Add(new AnalyzeReslut(vSyntaxItem,
Regex.Match(vCode, vSyntaxItem.Pattern,
vSyntaxItem.Options).Value));
vCode = Regex.Replace(vCode, vSyntaxItem.Pattern, " ",
vSyntaxItem.Options);
vFind = true;
break;
}
}
}
return true;
}
}

class CSharpEngine : SyntaxEngine
{
public CSharpEngine()
{
SyntaxItems.Add(new SyntaxItem(@ "^\s+ ", RegexOptions.None,
"空白 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^\/\/[^\n]*[\n]? ", RegexOptions.None,
"单行注释 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^\/\*[^\*]*\*\/ ", RegexOptions.None,
"多行注释 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^#\s*(define|elif|else|endif|endregion| " +
@ "error|if|line|pragma|region|undef|using|warning)\s* ", RegexOptions.None,
"指令 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^(abstract|event|new|struct|as|explicit| " +


@ "null|switch|base|extern|object|this|bool|false|operator|throw|break| " +
@ "finally|out|true|byte|fixed|override|try|case|float|params|typeof| " +
@ "catch|for|private|uint|char|foreach|protected|ulong|checked|goto| " +
@ "public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort| " +
@ "continue|int|return|using|decimal|in|sbyte|virtual|default|interface| " +
@ "sealed|volatile|delegate|internal|short|void|do|is|sizeof|while| " +
@ "double|lock|stackalloc|else|long|static|enum|namespace|string)\s* ",
RegexOptions.None, "关键字 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^(get|partial|set|value|where|yield)\s* ",
RegexOptions.None, "上下文关键字 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(
@ "^[\~\!\@\#\$\%\^\&\*\(\)_\+\-\=\{\}\[\]\\\|\;\\:\ <\> \?\,\.\/]+ ",
RegexOptions.None, "标点符号 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^\d+ ", RegexOptions.None,
"整数 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^0x[\da-f]+ ", RegexOptions.IgnoreCase,
"十六进制数 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^(\@)?\ " "[^\ " "]*\ " " ", RegexOptions.None,
"字符串 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^\ '[^\ ']*\ ' ", RegexOptions.None,
"字符 ", SyntaxItems.Count));
SyntaxItems.Add(new SyntaxItem(@ "^\w* ", RegexOptions.None,
"标识符 ", SyntaxItems.Count));
}
}


------解决方案--------------------


学习..

支持一下...
[解决办法]
zswang兄的,支持一下,先顶再看
[解决办法]
不错...
[解决办法]
这个..

比较耗时.
[解决办法]
呵呵,工作量不少啊,先支持一下
[解决办法]
楼主这个做的比较科研化...仅表示支持吧.
[解决办法]
学习,拷走收藏
[解决办法]
呵呵,支持一下
[解决办法]
study
[解决办法]
学习
[解决办法]
学习....UP
[解决办法]
(\b(int)\b)|(\b(in)\b)|(\b(else)\b)

(? <=[\s+\=\;\(])([\-]?\d{1,}[\.]\d{1,})|([\-]?\d{1,})(?=[\s+\=\)\;])

嘻嘻~粹下。。
正加起到一天....
[解决办法]
天才,收藏学习
[解决办法]
学习下..........
[解决办法]
mark~
[解决办法]
1.
这些数字出现的情况不知道全没?
============================
指数带正负号的好像也支持:如1.2E+7

2.
正则中注意\b的使用.
[解决办法]
收藏
[解决办法]
真不错,收藏,回去再研究研究。

[解决办法]
恩,刚才上CodeProject看到了...
[解决办法]
Mark

读书人网 >C#

热点推荐