使用 antlr 3 解析 Union[Dict[str,str],Dict[str,str]]

Parsing Union[Dict[str,str],Dict[str,str]] with antlr 3

我正在尝试使用 antlr3 为诸如“Union[Dict[str,str],Dict[str,str]]”之类的字符串创建一个解析器。 下面是我用来生成解析器的解析器语法。

grammar PyType;

options {
  output=AST;
  ASTLabelType=CommonTree;
}

tokens {
    OPEN_SQ_BR = '[';
    CLOSE_SQ_BR = ']';
    LIST = 'List';
    SET = 'Set';
    UNION = 'Union';
    DICT = 'Dict';
    TUPLE = 'Tuple';
    COMMA = ',';
 /*   Nothing = 'nothing'; */
    OPTIONAL = 'Optional';
    HYPHEN = '-' ;
    UNDERSCORE = '_' ;
    DOT = '\.';
}


/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/
parse
    :  expr
    ;

list_element
    : OPEN_SQ_BR expr CLOSE_SQ_BR -> expr
    ;

union_element
    : OPEN_SQ_BR (expr COMMA)+ CLOSE_SQ_BR -> expr+;

list_expr
    : LIST^ list_element*;

set_expr
    : SET^ list_element*;

union_expr
    : UNION^ union_element;

dict_expr
    : DICT^ union_element;

tuple_expr
    : TUPLE^ union_element;

optional_expr
    : OPTIONAL^ union_element;


DIGIT  : '0'..'9' ;

LETTER : 'a'..'z' |'A'..'Z'|'0'..'9'|'_' ;

NUMBER : DIGIT+ ;

SimpleType : ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.')*('a'..'z'|'A'..'Z'|'_'|'0'..'9')
           ;


expr : list_expr
    | set_expr
    | SimpleType
    | union_expr
    | dict_expr
    | tuple_expr
    | optional_expr;

/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

使用上述语法正确解析了以下字符串。

  1. 联合[字典[str,str]]
  2. 字典[str,str]
  3. 列表[str]

但是,当我在 Union、Dict 或 Tuple 中有多个 Union、Dict 或 Tuple 时,它​​无法正确解析。例如 Union[Dict[str,str],Dict[str,str]] 没有正确解析。

有人可以帮我找出语法错误吗?

您的规则:

union_element
    : OPEN_SQ_BR (expr COMMA)+ CLOSE_SQ_BR -> expr+
    ;

不对:它说 expr 必须始终以 , 结尾,导致它不匹配 Union[Dict[str,str]](以及您到目前为止提到的所有其他输入示例如我所见)但匹配 Union[Dict[str,str,],] 之类的内容。

你应该这样做:

union_element
    : OPEN_SQ_BR expr (COMMA expr)* CLOSE_SQ_BR -> expr+
    ;

有了这个改变,我认为像 Union[Dict[str,str],Dict[str,str]] 这样的输入也会被正确匹配。