Lexicon.md

来自osdev
跳到导航 跳到搜索

Grammar Lexicon 语法词典

大多数程序员应该都熟悉ANTLR中出现的词汇,因为它遵循C及其派生语言的语法,并针对语法描述方向进行了一些扩展。

Comments 注释

有单行、多行、Javadoc风格的注释:

/** 这个grammar就是一个例子,说明了这三种写法
 * 注释。
 */
grammar T;
/* 多行
  注释
*/

/** 此rule匹配我的语言的declarator */
decl : ID ; // 匹配变量名

Javadoc注释对parser隐藏,被暂时忽略。 它们仅打算在grammar和任何rule开始时使用。

Identifiers 标识符

Token名称总是以大写字母开头,lexer rules也是如此,使用Java的Character.isUpperCase方法定义。 Parser rule名称总是以小写字母开头 (那些未通过 'Character.isUpperCase' 的名称)。 首字母后面可以是大小写字母、数字和下划线。 以下是一些示例名称:

ID, LPAREN, RIGHT_CURLY // token /lexer rules 名称
expr, simpleDeclarator, d2, header_file // parser rule名称

与Java一样,ANTLR接受ANTLR名称中的Unicode字符:

为了支持Unicode parser和lexer rule名称,ANTLR使用以下规则:

ID : a=NameStartChar NameChar*
     {  
     if ( Character.isUpperCase(getText().charAt(0)) ) setType(TOKEN_REF);
     else setType(RULE_REF);
     }  
   ;

Rule “NameChar” 标识了有效的Identifier字符:

fragment
NameChar
   : NameStartChar
   | '0'..'9'
   | '_'
   | '\u00B7'
   | '\u0300'..'\u036F'
   | '\u203F'..'\u2040'
   ;
fragment
NameStartChar
   : 'A'..'Z' | 'a'..'z'
   | '\u00C0'..'\u00D6'
   | '\u00D8'..'\u00F6'
   | '\u00F8'..'\u02FF'
   | '\u0370'..'\u037D'
   | '\u037F'..'\u1FFF'
   | '\u200C'..'\u200D'
   | '\u2070'..'\u218F'
   | '\u2C00'..'\u2FEF'
   | '\u3001'..'\uD7FF'
   | '\uF900'..'\uFDCF'
   | '\uFDF0'..'\uFFFD'
   ;

Rule 'NameStartChar'是可以开始Identifier(Rule、Token或Label名)的字符列表: 这些或多或少对应于Java的Character类中的isJavaIdentifierPartisJavaIdentifierStart。 如果语法文件不是UTF-8格式,请确保在ANTLR工具上使用 “-encoding” 选项,以便ANTLR正确读取字符。

Literals 文本

ANTLR不像大多数语言那样区分字符和字符串。 所有一个或多个字符长度的Literal字符串都用单引号括起来,例如 ’;’, ’if’, ’>=’, 和 ’\’’ (指包含单引号字符的一个字符串)。 Literals从不包含正则表达式。

Literals可以包含形式为’\uXXXX’ (对于直到’U+FFFF’的Unicode码点) 或 ’\u{XXXXXX}’ (对于所有Unicode码点) 的Unicode转义序列,其中’XXXX’是十六进制的Unicode码点值。

例如,’\u00E8’是带有重音的法语字母:’è’,而’\u{1F4A9}’是著名的表情符号:’💩’.

ANTLR还理解常见的特殊转义序列:’\n’(换行符)、 ’\r’(回车)、 ’\t’(制表符)、’\b’(退格)和’\f’(换页符)。 你可以直接在Literals中使用Unicode代码点,也可以使用Unicode转义序列:

grammar Foreign;
a : '外' ;

ANTLR生成的识别器采用包含所有Unicode字符的字符词汇表。 运行时库假定的输入文件编码取决于目标语言。 对于Java目标,运行库假设文件是UTF-8格式的。 使用CharStreams中的工厂方法,你可以指定不同的编码。

Actions 动作

Actions是用目标语言编写的代码块。 你可以在Grammar中的许多位置使用Actions,但是语法始终是相同的:用大括号括起来的任意文本。 如果它在字符串或注释中,则不需要转义结束的花括号: "}" 或'/*}*/。 如果花括号是对齐的,你也不需要转义 }: {...}。 否则,用反斜杠转义多余的花括号:\{\}。 Action文本应符合语言选项中指定的目标语言。

嵌入式代码可以出现在:@header@members actions、parser和lexer rule、异常捕获规范、parser rules 的attribute部分(返回值、参数和局部变量),以及一些rule元素选项(当前为谓词)。

ANTLR在action内部所做的唯一解释行为与grammar attributes有关; 请参阅 Token Attributes 和第10章,Attributes and Actions。 嵌入在lexer rules中的Actions不会在emitted到生成的lexer中带有任何解释或翻译。

Keywords 关键字

以下是ANTLR语法中保留字的列表:

import, fragment, lexer, parser, grammar, returns,
locals, throws, catch, finally, mode, options, tokens

此外,尽管不是关键字,但不要将rule一词用作rule名称。 此外,不要将目标语言的任何关键字用作Token、Label或Rule名称。 例如,规则 if 将导致生成一个名为 if 的函数。 这显然是不可能的。