ANTLR4-在解析器规则中使用隐藏标记

ANTLR4-在解析器规则中使用隐藏标记,antlr,grammar,antlr4,Antlr,Grammar,Antlr4,我是ANTLR的一个彻头彻尾的笨蛋,如果这是一个非常基本的问题,我深表歉意 我试图解析一个具有奇怪的JSON语法的文件。这些文件是巨大的,数百MB,所以我避免创建解析树,我只是使用语法操作将数据处理成我想要的 像往常一样,我将向隐藏频道发送空格和换行符。但是,在一些情况下,如果我能检测到下一个字符是其中一个字符,这会很有帮助,因为这会限定属性值。 这是一个文件的摘录 game_speed=4 mapmode=0 dyn_title= { title="e_dyn_1887

我是ANTLR的一个彻头彻尾的笨蛋,如果这是一个非常基本的问题,我深表歉意

我试图解析一个具有奇怪的JSON语法的文件。这些文件是巨大的,数百MB,所以我避免创建解析树,我只是使用语法操作将数据处理成我想要的

像往常一样,我将向隐藏频道发送空格和换行符。但是,在一些情况下,如果我能检测到下一个字符是其中一个字符,这会很有帮助,因为这会限定属性值。 这是一个文件的摘录

  game_speed=4
  mapmode=0
  dyn_title=
  {
    title="e_dyn_188785"
    nick=nick_the_just          hist=yes
    base_title="k_mongolia"
    is_custom=yes
    is_dynamic=yes
    claim=
    {
      title=k_bulgaria
      pressed=yes
      weak=yes
    }
    claim=
    {
      title=c_karvuna
      pressed=yes
    }
    claim=
    {
      title=c_tyrnovo
    }
    claim=
    {
      title=c_mesembria
      pressed=yes
    }
  }
以下是我语法的相关部分:

property: key ASSIGNMENT value { insertProp(stack[scopeLevel], $key.text, currentVal) };

key: (LOWERCASE | UPPERCASE | UNDERSCORE | DIGIT | DOT | bool)+;
value: 
  bool { currentVal = $bool.text === 'yes' } 
  | string { currentVal = $string.text.replace(/\"/gi, '') } 
  | number { currentVal = parseFloat($number.text, 10) } 
  | date { currentVal = $date.text }
  | specific_value { currentVal = $specific_value.text }
  | (numberArray { currentVal = toArray($numberArray.text) }| array)
  | object
  ;

bool: 'yes' | 'no';
number: DASH? (DIGIT+ | (DIGIT+ '.' DIGIT+));
string:
  '"' 
  ( number
    | bool
    | specific_value 
    | NONALPLHA 
    | UNDERSCORE 
    | DOT 
    | OPEN_CURLY_BRACES 
    | CLOSE_CURLY_BRACES 
  )* 
  '"'
  ;

specific_value: (LOWERCASE | UPPERCASE | UNDERSCORE | DASH | bool)+ ;


WS: ([\t\r\n] | ' ') -> channel(HIDDEN);
NEWLINE: ( '\r'? '\n' | '\r')+ -> channel(HIDDEN);

因此,正如您所看到的,输入语法的属性值可以是字符串,但不能用
。事实上,出于某种奇怪的原因,有时下一个属性出现在同一行上。忽略WS和换行符意味着解析器无法识别
specific_值
规则终止,因此它也会获取下一个键的一部分。请参见下面的输出示例:

{
  game_speed: 4,
  mapmode: 0,
  dyn_title:
  { 
     title: 'e_dyn_188785',
     nick: 'nick_the_just\t\t\this',
     t: true,
     base_title: 'k_mongolia',
     is_custom: true,
     is_dynamic: true,
     claim: { title: 'k_bulgaria\n\t\t\t\tpresse', d: true, weak: true },
     claim2: { title: 'c_karvuna\n\t\t\t\tpresse', d: true },
     claim3: { title: 'c_tyrnovo' },
     claim4: { title: 'c_mesembria\n\t\t\t\tpresse', d: true 
  } 
},
这里有什么合适的解决方案来指定
specific\u value
在到达WS或换行符时不应抓取任何字符


提前谢谢!:D

我会在lexer中处理尽可能多的数据(如标识符、数字和字符串)。在您的案例中可能是这样的:

grammar JsonLike;

parse
 : object? EOF
 ;

object
 : '{' key_value* '}'
 ;

key_value
 : key '=' value
 ;

key
 : SPECIFIC_VALUE
 | BOOL
 // More tokens that can be a key?
 ;

value
 : object
 | array
 | BOOL
 | STRING
 | NUMBER
 | SPECIFIC_VALUE
 ;

array
 : '[' value+ ']'
 ;

BOOL
 : 'yes'
 | 'no'
 ;

STRING
 : '"' ( ~["\\] | '\\' ["\\] )* '"'
 ;

NUMBER
 : '-'? [0-9]+ ( '.' [0-9]+ )?
 ;

SPECIFIC_VALUE
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;

SPACES
 : [ \t\r\n]+ -> channel(HIDDEN)
 ;
导致以下解析:


我会在lexer中处理尽可能多的问题(如标识符、数字和字符串)。在您的案例中可能是这样的:

grammar JsonLike;

parse
 : object? EOF
 ;

object
 : '{' key_value* '}'
 ;

key_value
 : key '=' value
 ;

key
 : SPECIFIC_VALUE
 | BOOL
 // More tokens that can be a key?
 ;

value
 : object
 | array
 | BOOL
 | STRING
 | NUMBER
 | SPECIFIC_VALUE
 ;

array
 : '[' value+ ']'
 ;

BOOL
 : 'yes'
 | 'no'
 ;

STRING
 : '"' ( ~["\\] | '\\' ["\\] )* '"'
 ;

NUMBER
 : '-'? [0-9]+ ( '.' [0-9]+ )?
 ;

SPECIFIC_VALUE
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;

SPACES
 : [ \t\r\n]+ -> channel(HIDDEN)
 ;
导致以下解析:


为什么不在lexer阶段处理字符串和数字?疏忽?缺乏经验?只是不想那样做?我不知道这会有什么帮助?通过在解析器中将
specific_值
-字符(和
string
-字符和
number
-字符)粘在一起,您很难确定
ab
是单个
特定_值
ab
)还是2个
特定_值
a
b
)因为lexer将中间的空间放在不同的频道上。在lexer中处理此类情况将消除这种情况。我将编写一个快速演示。啊哈!是的,这很有意义,我将尝试一下!谢谢!如果可以,我仍然非常感谢简短的演示:)没问题。添加了一个快速演示。为什么不在lexer阶段处理字符串和数字?疏忽?缺乏经验?只是不想那样做?我不知道这会有什么帮助?通过在解析器中将
specific_值
-字符(和
string
-字符和
number
-字符)粘在一起,您很难确定
ab
是单个
特定_值
ab
)还是2个
特定_值
a
b
)因为lexer将中间的空间放在不同的频道上。在lexer中处理此类情况将消除这种情况。我将编写一个快速演示。啊哈!是的,这很有意义,我将尝试一下!谢谢!如果可以,我仍然非常感谢简短的演示:)没问题。添加了一个快速演示。