簡體   English   中英

ANTLR-加入令牌以輸出

[英]ANTLR - Join tokens to output

使用ANTLR3,我想解析如下字符串:

  • 名稱不能為空,年齡不能為 (14,15)

對於這些情況,我想獲得以下AST:

  n0 [label="QUERY"];
  n1 [label="AND"];
  n1 [label="AND"];
  n2 [label="IS NOT"];
  n2 [label="IS NOT"];
  n3 [label="name"];
  n4 [label="empty"];
  n5 [label="NOT IN"];
  n5 [label="NOT IN"];
  n6 [label="age"];
  n7 [label="14"];
  n8 [label="15"];

  n0 -> n1 // "QUERY" -> "AND"
  n1 -> n2 // "AND" -> "IS NOT"
  n2 -> n3 // "IS NOT" -> "name"
  n2 -> n4 // "IS NOT" -> "empty"
  n1 -> n5 // "AND" -> "NOT IN"
  n5 -> n6 // "NOT IN" -> "age"
  n5 -> n7 // "NOT IN" -> "14"
  n5 -> n8 // "NOT IN" -> "15"

但是我的n2和n5節點看起來像:n2 [label =“ IS”]; n5 [label =“ NOT”];

即,僅出現第一個單詞。 我怎樣才能將兩個令牌一起加入?

我的語法是:

query
    :   expr EOF   ->   ^(QUERY expr)
    ;

expr
    :   logical_expr
    ;

logical_expr
    :   equality_expr (logical_op^ equality_expr)*
    ;

equality_expr
    :   ID equality_op+ atom    -> ^(equality_op ID atom)
    |   '(' expr ')'    ->  ^('(' expr)
    ;

atom
    :   ID
    |   id_list
    |   Int
    |   Number
    |   String
    |   '*'
    ;

id_list
    :   '(' ID (',' ID)+ ')'    ->  ID+
    |   '(' Number (',' Number)* ')' -> Number+
    |   '(' String (',' String)* ')' -> String+
    ;

equality_op
    :   'IN'
    |   'IS'
    |   'NOT'
    |   'in'
    |   'is'
    |   'not'
    ;

logical_op
    :   'AND'
    |   'OR'
    |   'and'
    |   'or'
    ;

Number
    :   Int ('.' Digit*)?
    ;

ID
    :   ('a'..'z' | 'A'..'Z' | '_' | '.' | '-' | '*' | '/' | ':' | Digit)* 
    ;

String
@after {
    setText(getText().substring(1, getText().length()-1).replaceAll("\\\\(.)", "$1"));
    }
    :  '"'  (~('"' | '\\')  | '\\' ('\\' | '"'))* '"' 
    |  '\'' (~('\'' | '\\') | '\\' ('\\' | '\''))* '\''
    ;

Comment
    :  '//' ~('\r' | '\n')* {skip();}
    |  '/*' .* '*/'         {skip();}
    ;

Space
    :  (' ' | '\t' | '\r' | '\n' | '\u000C') {skip();}
    ;

fragment Int
    :  '1'..'9' Digit*
    |  '0'
    ;

fragment Digit 
    :  '0'..'9'
    ;

indexes
    :  ('[' expr ']')+ -> ^(INDEXES expr+)
    ;

做類似這樣的事情(檢查我添加的內聯注釋):

tokens {
  IS_NOT; // added
  NOT_IN; // added
  QUERY;
  INDEXES;
}

query
    :   expr EOF   ->   ^(QUERY expr)
    ;

expr
    :   logical_expr
    ;

logical_expr
    :   equality_expr (logical_op^ equality_expr)*
    ;

equality_expr
    :   ID equality_op atom    -> ^(equality_op ID atom) // changed equality_op+ to equality_op
    |   '(' expr ')'    ->  ^('(' expr)
    ;

atom
    :   ID
    |   id_list
    |   Int
    |   Number
    |   String
    |   '*'
    ;

id_list
    :   '(' ID (',' ID)+ ')'    ->  ID+
    |   '(' Number (',' Number)* ')' -> Number+
    |   '(' String (',' String)* ')' -> String+
    ;

equality_op
    :   IS NOT -> IS_NOT // added
    |   NOT IN -> NOT_IN // added
    |   IN
    |   IS
    |   NOT
    ;

logical_op
    :   AND
    |   OR
    ;

IS : 'IS' | 'is'; // added
NOT : 'NOT' | 'not'; // added
IN : 'IN' | 'in'; // added
AND : 'AND' | 'and'; // added
OR : 'OR' | 'or'; // added

Number
    :   Int ('.' Digit*)?
    ;

ID
    :   ('a'..'z' | 'A'..'Z' | '_' | '.' | '-' | '*' | '/' | ':' | Digit)+ 
    ;

String
@after {
    setText(getText().substring(1, getText().length()-1).replaceAll("\\\\(.)", "$1"));
    }
    :  '"'  (~('"' | '\\')  | '\\' ('\\' | '"'))* '"' 
    |  '\'' (~('\'' | '\\') | '\\' ('\\' | '\''))* '\''
    ;

Comment
    :  '//' ~('\r' | '\n')* {skip();}
    |  '/*' .* '*/'         {skip();}
    ;

Space
    :  (' ' | '\t' | '\r' | '\n' | '\u000C') {skip();}
    ;

fragment Int
    :  '1'..'9' Digit*
    |  '0'
    ;

fragment Digit 
    :  '0'..'9'
    ;

indexes
    :  ('[' expr ']')+ -> ^(INDEXES expr+)
    ;

產生以下AST:

在此處輸入圖片說明

此外,詞法分析器規則應始終至少匹配1個字符(我之前已經向您提到過)。 您的詞法分析器規則ID可能匹配0個字符。

問題在於,equityop +僅具有第一個匹配項的值。 我看到了不同的解決方法:創建特定的規則(如果只是用於是否存在),創建子規則或連接變量,如我在此處所做的:

equality_expr
    :   ID (full_op+=equality_op) + atom    -> ^(full_op ID atom)
    |   '(' expr ')'    ->  ^('(' expr)
    ;

下面的問題是不同的,但給我的主意: Antlr AST產生(可能)瘋狂

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM