使用 C# 目标一次性创建模型树层次结构

发布于 2024-11-15 13:04:15 字数 2664 浏览 3 评论 0原文

简而言之,我想知道如何在 ANTLR 语法中一次性正确构建模型层次结构,以及当前 C# 代码生成的正确方法是什么。正如文档中所述,访问返回变量当前似乎不起作用。

请参阅文档中的此示例

field
    : d=decl ';' {System.out.println("type "+$d.type+", vars="+$d.vars);}
    ;
decl returns [String type, List vars]
    : t=type ids+=ID (',' ids+=ID)* {$type = $t.text; $vars = $ids;}
    ;

我的实现是用 C# 编写的,但是 C#目标文档(大约 2008 年?)没有提到语法中与标准操作模式的任何偏差。由于这个。我的实现基本上使用嵌套的 innerStats 填充 1 深的树层次结构:

alias returns [IStatement alias]
    // Alias(string identifier, List<Statement> value, StatementType statementType, MetaData metaData)
    @init { List<IStatement> innerList = new List<IStatement>(); }
    :   ^(ALIAS ID ( id=innerStat{if($id != null) {innerList.Add($id.myInnerStat);}} )+ ) {$alias = new Alias($ID.ToString(), innerList , StatementType.Alias, null) as IStatement; }
    ;

innerStat returns [IStatement myInnerStat]
    :   s=simpleAlias { myInnerStat = $s; }
    |   s=simpleBind { myInnerStat = $s; }
    |   s=command { myInnerStat = $s; }
    |   increment { myInnerStat = null; }
    |   s=exec { myInnerStat = $s; }
    ;

simpleAlias returns [IStatement myAlias]
    // Alias(string identifier, List<Statement> value, StatementType statementType, MetaData metaData)
    @init{ myAlias= null; string id1 = null; string id2 = null; }
    @after{ myAlias = (new Alias(id1, id2, StatementType.Alias, null)) as IStatement; }
    :   ^(ALIAS ID) { id1 = $ID.ToString(); }
    |   ^(ALIAS i1=ID i2=ID) { id1 = $i1.ToString(); id2 = $i2.ToString(); }
    ;

这会返回以下错误:

error(117): D:/Files/.../SourceEval.g:39:29: missing attribute access on rule scope: id
error(117): D:/Files/.../SourceEval.g:43:18: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:44:17: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:45:14: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:47:11: missing attribute access on rule scope: s

目前,我看到解决此问题的唯一方法是在我的 C# 模型中创建一个方法,然后调用 Model.Aliases .Last().AddChild(IStatement) 来自innerStat,这破坏了封装。感谢您的任何帮助。

编辑:更正后的代码可以在这里找到: https ://github.com/keithharvey/Script-Parser/blob/master/Installer/Model/DAL/SourceExpr.g

In short, I'm wondering how to properly build model hierarchies from within an ANTLR grammar in one pass and what the proper way to do that is with the current C# code generation. Accessing return variables does not currently seem to work, as described in the docs.

See this example from the documentation

field
    : d=decl ';' {System.out.println("type "+$d.type+", vars="+$d.vars);}
    ;
decl returns [String type, List vars]
    : t=type ids+=ID (',' ids+=ID)* {$type = $t.text; $vars = $ids;}
    ;

My implementation is in C#, but the C# target documentation (circa 2008?) doesn't mention any deviations from the standard action pattern within grammars. I'm using ANTLRWorks 1.4 (not the latest 1.4.2 as of this writing) due to this. My implementation, which basically populates a 1 deep tree hierarchy with nested innerStats:

alias returns [IStatement alias]
    // Alias(string identifier, List<Statement> value, StatementType statementType, MetaData metaData)
    @init { List<IStatement> innerList = new List<IStatement>(); }
    :   ^(ALIAS ID ( id=innerStat{if($id != null) {innerList.Add($id.myInnerStat);}} )+ ) {$alias = new Alias($ID.ToString(), innerList , StatementType.Alias, null) as IStatement; }
    ;

innerStat returns [IStatement myInnerStat]
    :   s=simpleAlias { myInnerStat = $s; }
    |   s=simpleBind { myInnerStat = $s; }
    |   s=command { myInnerStat = $s; }
    |   increment { myInnerStat = null; }
    |   s=exec { myInnerStat = $s; }
    ;

simpleAlias returns [IStatement myAlias]
    // Alias(string identifier, List<Statement> value, StatementType statementType, MetaData metaData)
    @init{ myAlias= null; string id1 = null; string id2 = null; }
    @after{ myAlias = (new Alias(id1, id2, StatementType.Alias, null)) as IStatement; }
    :   ^(ALIAS ID) { id1 = $ID.ToString(); }
    |   ^(ALIAS i1=ID i2=ID) { id1 = $i1.ToString(); id2 = $i2.ToString(); }
    ;

This returns the following errors:

error(117): D:/Files/.../SourceEval.g:39:29: missing attribute access on rule scope: id
error(117): D:/Files/.../SourceEval.g:43:18: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:44:17: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:45:14: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:47:11: missing attribute access on rule scope: s

Currently, the only way I see to around this problem is to create a method within my C# model and then call Model.Aliases.Last().AddChild(IStatement) from within innerStat, which breaks encapsulation. Thanks for any help.

edit: The corrected code can be found here: https://github.com/keithharvey/Script-Parser/blob/master/Installer/Model/DAL/SourceExpr.g

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兔小萌 2024-11-22 13:04:15

请注意这些示例如何始终引用规则的属性:

$d.type
$d.vars
$t.text

$ids 除外,但该属性不是规则,因为 += 使其成为 列表

您的代码有 5 次非法使用规则属性(或缺少规则属性):

1

$id != null 无效,因为您根本没有使用属性,请尝试: $id .myInnerStat != null 相反。

2

s=exec { myInnerStat = $s; } 是错误的,因为您根本没有使用属性,您需要访问 exec 的属性(您没有发布该规则,所以我不知道是什么) 。

3、4、5

$ID.ToString()$i1.ToString()$i2.ToString() 是错误的,< code>ToString() 不是 ID 的有效属性。尝试使用 $ID.text 等代替。

Notice how the examples always refer to an attribute of a rule:

$d.type
$d.vars
$t.text

except the $ids, but that one isn't a rule because the += makes it a List.

Your code has 5 illegal usages of rule attributes (or the absence of them):

1

$id != null is invalid because you didn't use an attribute at all, try: $id.myInnerStat != null instead.

2

s=exec { myInnerStat = $s; } is wrong because you didn't use an attribute at all, you need to access an attribute of exec (you didn't post that rule, so I don't know what).

3, 4, 5

$ID.ToString(), $i1.ToString() and $i2.ToString() are wrong, ToString() isn't an valid attribute of ID. Try $ID.text, etc. instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文