Antlr3 .Net如何构建简单的语法

时间:2012-03-08 17:15:41

标签: antlr antlr3

我正在尝试构建一个简单的语法来解析.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,让我可以浏览类型。

1 个答案:

答案 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:

enter image description here

有关使用ANTLR创建AST的更多信息:How to output the AST built using ANTLR?