如何解析c#代码,然后将其序列化回文本文件

本文关键字:序列化 回文 文本 文件 然后 何解析 代码 | 更新日期: 2023-09-27 17:49:27

我发现有c# antlr4语法。我为该语法构建了c#的antlr4解析器。它的工作原理。我可以遍历解析树,看到有一些节点有一些子节点。

现在我想从这个解析树生成c#源代码。

我能以某种方式生成(语法外)反antlr解析器,而不是解析,当给定的解析树将生成源代码,将导致这个解析树?

编辑:

我目前在CoffeeScript中的尝试是使用原始源代码和antlr放入节点的开始和停止位置来遍历源代码树,然后再次遍历以打印源代码。唯一的问题是多个节点在源代码中完全相同的空间开始。为了解决这个问题,我使用了一些令人讨厌的逻辑,将源片段仅放在最深处的节点:

antlr = require 'antlr4'
{CSharp4Parser} = require './CSharp4Parser'
{CSharp4Lexer} = require './CSharp4Lexer'
input = "namespace A { class B {}; class C {} }"
cstream = new antlr.InputStream(input)
lexer = new CSharp4Lexer(cstream)
tstream = new antlr.CommonTokenStream(lexer)
parser = new CSharp4Parser(tstream)
parser.buildParseTrees = true ;
tree = parser.compilation_unit();
decorateWithSource = new antlr.tree.ParseTreeListener();
start =
  prev: null
stop =
  prev: null
o = (msg) -> process.stdout.write(msg)
decorateWithSource.enterEveryRule = (a) ->
  if start.prev
    start.prev.before = input.substr(start.prev.start.start, a.start.start - start.prev.start.start)
  if stop.prev
    stop.prev.after = input.substr(stop.prev.stop.start, a.start.start - stop.prev.stop.start)
  start.prev = a
  stop.prev = null
decorateWithSource.exitEveryRule = (a) ->
  if start.prev
    start.prev.before = input.substr(start.prev.start.start, a.stop.start - start.prev.start.start)
  if stop.prev
    stop.prev.after = input.substr(stop.prev.stop.start, a.stop.start - stop.prev.stop.start)
  start.prev = null
  stop.prev = a
walker = new antlr.tree.ParseTreeWalker();
walker.walk(decorateWithSource, tree);
stop.prev.after = input.substr(stop.prev.stop.start)
printOut = new antlr.tree.ParseTreeListener();
printOut.enterEveryRule = (a) ->
  o (a.before || ''), ' -> '+parser.ruleNames[a.ruleIndex]
printOut.exitEveryRule = (a) ->
  o (a.after || ''), ' < '+parser.ruleNames[a.ruleIndex]
walker.walk(printOut, tree);

我要做的是读取c#源文件(来自重新编译的一些东西)到树中,然后通过用OMeta编写的转换器传递它(这将我的环境缩小到具有OMeta实现的语言,如c#, js或coffeescript,可能还有其他),然后写回固定的源代码。

也许手动遍历解析树来生成代码对我来说已经足够好了。

如何解析c#代码,然后将其序列化回文本文件

不容易;ANTLR的设计初衷并不是这样的。

您可以研究StringTemplates,它将允许您遍历树并生成大致正确的代码。

如果您想详细地重新生成源代码,这是不够的。