Antlr 分析不同词类的句子

Antlr 分析不同词类的句子,antlr,whitespace,grammar,words,sentence,Antlr,Whitespace,Grammar,Words,Sentence,我在找一个语法来分析两种类型的句子 指由空格分隔的单词: ID1:单词不以数字开头的句子 ID2:不以数字和数字开头的句子 基本上,语法的结构应该是 ID1 separator ID2 ID1: Word can contain number like Var1234 but not start with a number ID2: Same as above but 1234 is allowed separator: e. g. '=' @巴特 我刚刚尝试添加两个标记“和

我在找一个语法来分析两种类型的句子 指由空格分隔的单词:

  • ID1:单词不以数字开头的句子
  • ID2:不以数字和数字开头的句子
  • 基本上,语法的结构应该是

    ID1 separator ID2  
    
    ID1: Word can contain number like Var1234 but not start with a number  
    
    ID2: Same as above but 1234 is allowed  
    
    separator: e. g. '='
    
    @巴特
    我刚刚尝试添加两个标记
    作为lexer规则
    特殊
    ,以便以后在lexer规则
    Word中使用。
    即使我没有在下面的语法中使用
    Special
    ,我在AntlWorks 1.4.2中也会遇到以下错误:
    以下令牌定义永远无法匹配,因为先前的令牌匹配相同的输入:特殊
    但是当我在
    特殊的
    之前添加
    片段时,我没有得到那个错误。为什么

    grammar Sentence1b1;
    
    tokens
    {
      TCUnderscore  = '_' ;
      TCQuote       = '"' ;
    }
    
    assignment
      :  id1 '=' id2
      ;
    
    id1
      :  Word+
      ;
    
    id2
      :  ( Word | Int )+
      ;
    
    Int
      :  Digit+
      ;
    
    // A word must start with a letter
    Word
      :  ( 'a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | Digit )*
      ;
    
    Special
      : ( TCUnderscore | TCQuote )
      ;
    
    Space
      :  ( ' ' | '\t' | '\r' | '\n' ) { $channel = HIDDEN; }
      ;
    
    fragment Digit
      :  '0'..'9'
      ;
    
    Lexer rule
    Special
    应在Lexer rule
    Word
    中使用:

    Word
      :  ( 'a'..'z' | 'A'..'Z' | Special ) ('a'..'z' | 'A'..'Z' | Special | Digit )*
      ;
    

    我不确定这是否符合你的需要,但在巴特的帮助下,在我的帖子里 我想到了这个语法:

    grammar PropertyAssignment;
    
    assignment
        : id_nodigitstart '=' id_digitstart EOF
        ;
    
    id_nodigitstart
        :   ID_NODIGITSTART+
        ;
    
    id_digitstart
        :   (ID_DIGITSTART|ID_NODIGITSTART)+
        ;
    
    ID_NODIGITSTART
        :   ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*
        ;           
    
    ID_DIGITSTART
        :   ('0'..'9'|'a'..'z'|'A'..'Z')+
        ;
    
    WS  :   (' ')+ {skip();}
        ;
    

    “a name=my 4value”有效,而“4a name=my 4value”会导致异常。

    我不确定这是否符合您的需要,但在我的帖子中有巴特的帮助 我想到了这个语法:

    grammar PropertyAssignment;
    
    assignment
        : id_nodigitstart '=' id_digitstart EOF
        ;
    
    id_nodigitstart
        :   ID_NODIGITSTART+
        ;
    
    id_digitstart
        :   (ID_DIGITSTART|ID_NODIGITSTART)+
        ;
    
    ID_NODIGITSTART
        :   ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*
        ;           
    
    ID_DIGITSTART
        :   ('0'..'9'|'a'..'z'|'A'..'Z')+
        ;
    
    WS  :   (' ')+ {skip();}
        ;
    

    “a name=my 4value”起作用,而“4a name=my 4value”引起异常。

    我会选择这样的方式:

    grammar Sentence;
    
    assignment
      :  id1 '=' id2
      ;
    
    id1
      :  Word+
      ;
    
    id2
      :  (Word | Int)+
      ;
    
    Int
      :  Digit+
      ;
    
    // A word must start with a letter
    Word
      :  ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | Digit)*
      ;
    
    Space
      :  (' ' | '\t' | '\r' | '\n') {skip();}
      ;
    
    fragment Digit
      :  '0'..'9'
      ;
    
    这将解析输入:

    Word可以包含类似Var1234的数字,但不能以与上面相同的数字开头,但允许使用1234

    详情如下:

    编辑 为了将lexer规则很好地打包在一起,我将它们全部放在语法的底部,而不是部分放在
    tokens{…}
    块中,我只使用它来定义“虚构的标记”(在AST创建中使用):

    现在,按照上述规则,
    tcunderline
    TCQuote
    永远不能成为令牌,因为当lexer偶然发现一个
    \u
    时,就会创建一个
    特殊的
    令牌。或者在这种情况下:

    // wrong!
    TCUnderscore : '_';
    TCQuote      : '"';
    Special      : (TCUnderscore | TCQuote);
    
    由于lexer将首先创建
    tcunderline
    TCQuote
    标记,因此无法创建
    Special
    标记。因此出现了错误:

    The following token definitions can never be matched because prior tokens match the same input: ...
    
    如果将
    tcunderline
    TCQuote
    设置为
    fragment
    规则,则不会出现该问题,因为
    fragment
    规则仅“服务”其他lexer规则。所以这是可行的:

    // good!
    Special               : (TCUnderscore | TCQuote);
    fragment TCUnderscore : '_';
    fragment TCQuote      : '"';
    
    此外,
    fragment
    规则在任何解析器规则中都不能“可见”(lexer永远不会创建
    tcunderline
    TCQuote
    标记!)


    我喜欢这样的东西:

    grammar Sentence;
    
    assignment
      :  id1 '=' id2
      ;
    
    id1
      :  Word+
      ;
    
    id2
      :  (Word | Int)+
      ;
    
    Int
      :  Digit+
      ;
    
    // A word must start with a letter
    Word
      :  ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | Digit)*
      ;
    
    Space
      :  (' ' | '\t' | '\r' | '\n') {skip();}
      ;
    
    fragment Digit
      :  '0'..'9'
      ;
    
    这将解析输入:

    Word可以包含类似Var1234的数字,但不能以与上面相同的数字开头,但允许使用1234

    详情如下:

    编辑 为了将lexer规则很好地打包在一起,我将它们全部放在语法的底部,而不是部分放在
    tokens{…}
    块中,我只使用它来定义“虚构的标记”(在AST创建中使用):

    现在,按照上述规则,
    tcunderline
    TCQuote
    永远不能成为令牌,因为当lexer偶然发现一个
    \uu
    ,就会创建一个
    特殊的
    令牌。或者在这种情况下:

    // wrong!
    TCUnderscore : '_';
    TCQuote      : '"';
    Special      : (TCUnderscore | TCQuote);
    
    由于lexer将首先创建
    tcunderline
    TCQuote
    标记,因此无法创建
    Special
    标记。因此出现错误:

    The following token definitions can never be matched because prior tokens match the same input: ...
    
    如果将
    tcunderline
    TCQuote
    设置为
    fragment
    规则,则不会出现此问题,因为
    fragment
    规则仅“服务”其他lexer规则。因此,此操作:

    // good!
    Special               : (TCUnderscore | TCQuote);
    fragment TCUnderscore : '_';
    fragment TCQuote      : '"';
    
    此外,
    fragment
    规则在任何解析器规则中都不能“可见”(lexer永远不会创建
    tcunderline
    TCQuote
    标记!)


    你对这两种不同类型的句子的定义可以用几种方式来解释(我假设你只指一种特定的方式:))。你能给出这两种句子的一些具体例子吗?谢谢!你可以用新信息编辑你的原始问题。不过我不会发布HTML,看看如何正确设置问题的格式。谢谢Bart,我原始问题中的附加问题。没问题,请看我的编辑。你对这两种不同句子的定义句子的类型可以用几种方式来解释(我想你只指一种特定的方式:))。你能给出这两类句子的一些具体例子吗?谢谢!你可以用新信息编辑你的原始问题。不过我不会发布HTML,看看如何正确设置问题的格式。谢谢Bart,我原始问题中的附加问题。没问题,请看我的编辑。EOF的定义在哪里?@AntlStarter,
    EOF
    是一个内置令牌(代表文件的结尾)。EOF在哪里定义?@ANTLRStarter,
    EOF
    是一个内置令牌(代表文件的结尾)。