我正在尝试构建一个简单的语法来解析.Net类型的名称字符串,支持泛型。我承认在任何语言中构建语法都是全新的。类型字符串可能如下所示。
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,让我可以浏览类型。
答案 0 :(得分:2)
不,你不应该使用树语法。在解析器创建AST之后,使用树语法。只需从中删除关键字tree
。
其他一些评论:
type
,但您使用的type (SEP type)?
与一个或两个type
匹配。您需要type (SEP type)*
代替.
s中的type
; 这样的事情很可能会成功:
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哪些节点/令牌是根令牌,哪些节点/令牌是丢弃的(如逗号,括号,......)。
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();}
;
创建以下AST:
有关使用ANTLR创建AST的更多信息:How to output the AST built using ANTLR?