如何使用组名使用正则表达式实现有效的令牌生成器

时间:2018-10-14 13:10:57

标签: c# regex parsing tokenize lexical-analysis

我正在尝试编写一个用于使用Regex解析文本主体(输入字符串)的标记器。我想要的是将输入拆分为单独的令牌,并将其存储在List 中,其中令牌是(C#)类,如

class Token {
  string value;
  string type; // "identifier", "string', "intliteral', ... 
}

我想使用以下正则表达式来分割输入字符串:

public static Regex tokenPattern = new Regex (
@"
  ( (?<identifier>(?:\p{L}|_)\w*)
  | (?<string>""[^""]*"")
  | (?<intliteral>(?:-|\+)?\d+[^\.])
  | (?<realliteral>(?:-|\+)?\d+(?:\.\d+)?)
  | (?<comma>,)
  | (?<lpar>\()
  | (?<rpar>\))
  | ...
  | (?<undefined>[^\s]*?)
  )
",
  RegexOptions.ExplicitCapture |
  RegexOptions.IgnorePatternWhitespace | 
  ...
);

我的问题是,很容易获得每个令牌的 value 部分,但是似乎没有一种简单的方法来获得 type 部分,即组名。我希望正则表达式组具有一个包含“标识符”等的 Name 属性,但事实并非如此。

有没有一种方法可以确定组名,而不用遍历每个令牌的所有组名/编号? (即一种使用O(n)而不是O(nm)的复杂度,输入字符串中的令牌数量为n,令牌类型为m的方法)

1 个答案:

答案 0 :(得分:0)

这将是一个多阶段操作,而使用一个正则表达式来执行这种操作将不会很好地利用处理器时间。我建议对操作的各个阶段进行划分,例如:

  1. 使用基本正则表达式将每个值解析到令牌中。
  2. 进行特定操作以识别遇到的令牌类型并相应地设置该值。

第二步之后,您最需要继续打破这些步骤,以实现更高的效率。


我必须同意这样一种观点,即正则表达式不是用于识别过去单个令牌或在令牌过程中用于子代识别令牌属性的令牌语言处理工具。