当前位置: 首页 > 知识库问答 >
问题:

“identifier”规则也使用ANTLR Lexer语法中的关键字

应志用
2023-03-14

在使用ANTLR3.5语法进行Java语法分析时,注意到“标识符”规则在Antlr Lexer语法中消耗了很少的关键字。Lexer语法是

lexer grammar JavaLexer;

options {
   //k=8;
   language=Java;
   filter=true;
   //backtrack=true;
}

@lexer::header {
package java;
}

@lexer::members {
public ArrayList<String> keywordsList = new ArrayList<String>();
}

V_DECLARATION
:
( ((MODIFIERS)=>tok1=MODIFIERS WS+)? tok2=TYPE WS+ var=V_DECLARATOR WS* )
{...};

fragment
V_DECLARATOR
  :
  (
    tok=IDENTIFIER WS* ( ',' | ';' | ASSIGN WS* V_VALUE )
  )
  {...};

fragment
V_VALUE
: (IDENTIFIER (DOT WS* IDENTIFIER WS* '(' | ',' | ';'))
;

MODIFIERS
  :
  (PUBLIC | PRIVATE | FINAL)+
;

PRIVATE
    :    tok = 'private'
    { keywordsList.add($tok.getText());  }
    ;

PUBLIC
    :    tok = 'public'
    { keywordsList.add($tok.getText()); }
    ;

DOT
    :    '.'
    { keywordsList.add("."); }
    ;

THIS
    :    tok = 'this'
    { keywordsList.add($tok.getText()); }
    ;

ASSIGN
    :    '='
        { keywordsList.add("="); }
    ;    

IDENTIFIER:
  tok =Identifier
  {  
   //System.out.println("Identifier: " + $tok.text);
  }
  ;  

fragment
Identifier 
    :   (Letter (Letter|JavaIDDigit)*);

fragment
Letter
    :  '\u0024' |
       '\u0041'..'\u005a' |
       '\u005f' |
       '\u0061'..'\u007a' |
       '\u00c0'..'\u00d6' |
       '\u00d8'..'\u00f6' |
       '\u00f8'..'\u00ff' |
       '\u0100'..'\u1fff' |
       '\u3040'..'\u318f' |
       '\u3300'..'\u337f' |
       '\u3400'..'\u3d2d' |
       '\u4e00'..'\u9fff' |
       '\uf900'..'\ufaff'
    ;

fragment
JavaIDDigit
    :  '\u0030'..'\u0039' |
       '\u0660'..'\u0669' |
       '\u06f0'..'\u06f9' |
       '\u0966'..'\u096f' |
       '\u09e6'..'\u09ef' |
       '\u0a66'..'\u0a6f' |
       '\u0ae6'..'\u0aef' |
       '\u0b66'..'\u0b6f' |
       '\u0be7'..'\u0bef' |
       '\u0c66'..'\u0c6f' |
       '\u0ce6'..'\u0cef' |
       '\u0d66'..'\u0d6f' |
       '\u0e50'..'\u0e59' |
       '\u0ed0'..'\u0ed9' |
       '\u1040'..'\u1049'
   ;

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

当我试图解析行时:

public final int inch = this.getValue();

在Antlr语法中是否有任何技巧/规定来匹配关键字本身的规则,而不影响其他功能,如“标识符”?

共有1个答案

甄飞飙
2023-03-14

您的问题确实是由于对哪些属于lexer和哪些属于解析器的误解造成的:

  • lexer的工作是确定字符流代表哪些单词
    • 例如。thisthis0数字that标识符
    • 例如。该声明包含可能的修饰符、类型和标识符列表
    • 输入T
      • 可以是thisidentifier
      • 仍然可以thisidentifier
      • 不能再this,只能identifier
        null
        null

      另一个例子是:

      • 输入T,H,I,S
        • 可以作为thisidentifier整时间
        • 匹配
        • 不能再被任何东西匹配,因此this将被匹配为this(最上面的匹配规则),而不是标识符将启动一个新令牌

        现在说到重要的部分--只要一个lexer规则是从另一个lexer规则引用的,它就被认为仅仅是引用lexer规则的一个片段。这意味着匹配它不会发出一个新的令牌,也不会在片段匹配结束时触发多个匹配令牌之间的任何决策。因为this确实可以通过identifier规则匹配,所以整个声明符合v_declarathtml" target="_blank">ionlexer规则-所以除非有另一个lexer规则可以匹配至少相同长度的输入,并且在语法上比这个规则早,否则将应用这个规则。

        您没有提供任何引用this的规则,因此我们不知道这在语法中的具体情况,但明显的原因是,与使用this规则的任何东西相比,lexer可以匹配更长的输入或更早的规则。

 类似资料:
  • 正如维基百科关于解析的文章所指出的,这个过程有三个阶段: null 除了上面阶段(3)中的小困惑之外,我想验证我对ECMAScript过程的理解是否正确。 那么,下面的流程是正确的吗? 输入:Unicode码点流<--词法中的终端符号 输出:有效标记<--词法语法中的非终结符号 语法应用 分析每个Unicode码点(字符),每次一个 通过应用适当的产生式规则,将最长的终端符号序列替换为非终端符号

  • 主要内容:JSON 中的键,JSON 中的值,JSON 与 JavaScript 对象的区别JSON 的语法与 JavaScript 中的对象很像,在 JSON 中主要使用以下两种方式来表示数据: Object(对象):键/值对(名称/值)的集合,使用花括号定义。在每个键/值对中,以键开头,后跟一个冒号,最后是值。多个键/值对之间使用逗号分隔,例如; Array(数组):值的有序集合,使用方括号定义,数组中每个值之间使用逗号进行分隔。 下面展示了一个简单的 JSON 数据: 注意:所有

  • CSS 样式由一系列规则组成,这些规则由 Web 浏览器解析,然后应用于 HTML 文档相应的元素上。CSS 样式规则由三个部分组成,分别是选择器、属性和值: 选择器:由 HTML 元素的 id、class 属性或元素名本身以及一些特殊符号构成,用来指定要为哪个 HTML 元素定义样式,例如选择器就表示为页面中的所有标签定义样式; 属性:您希望给 HTML 元素设置的样式名称,由一系列关键词组成,

  • 我不明白关键字的区别("-

  • 我正在使用ANTLR4生成一个解析器。我是语法分析器的新手。我读过非常有帮助的ANTLR Mega教程,但我仍然停留在如何正确排序(和/或编写)我的lexer和解析器规则上。 我希望解析器能够处理以下内容: 你好< >,你好吗? 下面是我的语法: 旁注:我加了“punct?”在“item”规则的末尾,因为有可能在“func”后面出现一个逗号,例如在我上面给出的例句中。但由于“word”后面也可以有

  • 我正在寻找一种方法,防止在一个不需要关键词的地方匹配关键词。 看看下面的语法。“应用”和“输出”都是关键词。”OUTPUT'有一个包含任何字符的参数。 一切正常,但如果此参数包含单词APPLY,则会引发错误(外部输入APPLY预期规则_END)。 有办法解决这个问题吗?谢谢 示例文本 数字用户线