首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解析C#代码,然后将其序列化为文本文件

如何解析C#代码,然后将其序列化为文本文件
EN

Stack Overflow用户
提问于 2015-05-15 21:45:42
回答 1查看 601关注 0票数 2

我发现有C# antlr4语法。我为该语法为C#构建了antlr4解析器。它起作用了。我可以遍历解析树,并看到有一些节点具有一些子节点。

现在,我想从这个解析树重新生成C#源代码。

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

编辑:

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

代码语言:javascript
复制
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,可能还有其他语言),然后写回修复后的源代码。

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

EN

回答 1

Stack Overflow用户

发布于 2015-05-15 23:34:55

这并不容易;ANTLR实际上并不是为此而设计的。

您可以研究StringTemplates,它可以让您遍历整个树并输出大致正确的代码。

如果你想重新生成细节良好的源代码,这是不够的。请看我在How to build a prettyprinter上的回答。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30261095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档