Antlr Net如何构建一个简单的语法
我试图构建一个简单的语法来解析.Net类型的名称字符串,支持泛型。我承认对任何语言的语法都是全新的。类型字符串可能如下所示Antlr Net如何构建一个简单的语法,antlr,antlr3,Antlr,Antlr3,我试图构建一个简单的语法来解析.Net类型的名称字符串,支持泛型。我承认对任何语言的语法都是全新的。类型字符串可能如下所示 Foo.Bar.Blah(Mom.Dad, Son.Daughter(Frank.Bob), Dog) 基本上,它是递归的。你应该明白这一点 这件事让我完全不知所措。不知道如何开始。我目前构建的实际上不起作用的是: tree grammar XmlTypeName; options { language=CSharp2; } RPAREN : '('
Foo.Bar.Blah(Mom.Dad, Son.Daughter(Frank.Bob), Dog)
基本上,它是递归的。你应该明白这一点
这件事让我完全不知所措。不知道如何开始。我目前构建的实际上不起作用的是:
tree grammar XmlTypeName;
options {
language=CSharp2;
}
RPAREN
: '('
;
LPAREN
: ')'
;
SEP
: ','
;
TYPE
: ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+
;
prog
: type;
type
: TYPE (RPAREN type (SEP type)? LPAREN)? (EOF)?
;
这根本不起作用。Antlr3.exe抛出错误,指出树解析器中不允许使用RPARAM和LPARAM。树解析器是我所需要的吗
我想生成一个简单的AST,让我可以向下导航类型。不,不应该使用树语法。在解析器创建AST之后使用树语法。只需从中删除关键字
树
还有几句话:
- 您想在括号内匹配一个或多个逗号分隔的
s,但使用了类型
,它匹配一个或两个类型(SEP类型)
s。您将需要类型
李>类型(SEP类型)*
- 您没有说明
中的类型
李> - 您应该放弃lexer中的文字空格
grammar XmlTypeName;
options {
language=CSharp2;
}
prog
: type EOF
;
type
: name (RPAREN type (SEP type)* LPAREN)?
;
name
: ID (DOT ID)*
;
RPAREN
: '('
;
LPAREN
: ')'
;
SEP
: ','
;
DOT
: '.'
;
ID
: ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+
;
SPACE
: (' '|'\t')+ {Skip();} // if 'Skip()' doesn't work, try 'skip()'
;
然而,上面只是创建了一个简单的令牌列表。如果您想创建一个合适的AST,您需要“告诉”ANTLR哪些节点/令牌是根令牌,哪些要丢弃(如逗号、括号等)
这将创建以下AST:
有关使用ANTLR创建AST的更多信息:谢谢!大约两个小时后,我设法弄明白我需要拆分ID和“name”解析,其解析方式与类型列表的解析方式大致相同。但那只不过是一棵扁平的树。我还是有点不确定这里的语法到底是什么意思。->是重写,所以它改变了lexer中的标记。。。明白了。。。但是^()的意思是什么?没问题。AST运算符在我在答案末尾发布的链接中进行了解释。此外,它实际上在AST中发出名称“('TYPE','TYPE','TYPE')”。我如何让它从AST中隐藏('s)?或者我甚至应该麻烦吗?我显示它的方式,
'(“
,”)“
和”,“
从AST中被省略:试试看。同时阅读我在末尾发布的链接:它将解释如何在AST中省略或包含标记。@wasabi,如果您使用我的第二个示例,并且看到括号和逗号,您可能正在使用AntlWorks的解释器:不要,这有点错误。使用AntlWorks的调试器插件tead(显示创建的实际AST,而不仅仅是解析树)。
grammar XmlTypeName;
options {
output=AST;
language=CSharp2;
}
tokens {
TYPE;
NAME;
}
prog
: type EOF -> type
;
type
: name (RPAREN type (SEP type)* LPAREN)? -> ^(TYPE name type*)
;
name
: ID (DOT ID)* -> ^(NAME ID+)
;
RPAREN
: '('
;
LPAREN
: ')'
;
SEP
: ','
;
DOT
: '.'
;
ID
: ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+
;
SPACE
: (' '|'\t')+ {skip();}
;