附录 I:Lox 语法(Lox Grammar)
原文:Robert Nystrom, Crafting Interpreters, Appendix I。原书以 CC BY-NC-SA 4.0 协议发布;本译文用于学习与研究。
这里给出完整的 Lox 文法。各章在引入语言部分时都会给出对应规则;本附录将它们集中起来。
语法文法(Syntax Grammar)
语法文法将线性 token 序列解析为嵌套的语法树结构。它从能匹配完整 Lox 程序(或单条 REPL 输入)的第一条规则开始:
program -> declaration* EOF ;
声明(Declarations)
程序是一系列声明。声明包括绑定新标识符的语句,以及其他语句类型。
declaration -> classDecl
| funDecl
| varDecl
| statement ;
classDecl -> "class" IDENTIFIER ( "<" IDENTIFIER )?
"{" function* "}" ;
funDecl -> "fun" function ;
varDecl -> "var" IDENTIFIER ( "=" expression )? ";" ;
语句(Statements)
其余语句规则产生副作用,但不引入绑定。
statement -> exprStmt
| forStmt
| ifStmt
| printStmt
| returnStmt
| whileStmt
| block ;
exprStmt -> expression ";" ;
forStmt -> "for" "(" ( varDecl | exprStmt | ";" )
expression? ";"
expression? ")" statement ;
ifStmt -> "if" "(" expression ")" statement
( "else" statement )? ;
printStmt -> "print" expression ";" ;
returnStmt -> "return" expression? ";" ;
whileStmt -> "while" "(" expression ")" statement ;
block -> "{" declaration* "}" ;
注意,block 是一条语句规则,但也会作为非终结符出现在其他规则中,例如函数体。
表达式(Expressions)
表达式产生值。Lox 有多种优先级不同的一元与二元运算符。有些语言的文法不直接编码优先级、而在别处指定;这里为每个优先级层级单设规则,使关系清晰可见。
expression -> assignment ;
assignment -> ( call "." )? IDENTIFIER "=" assignment
| logic_or ;
logic_or -> logic_and ( "or" logic_and )* ;
logic_and -> equality ( "and" equality )* ;
equality -> comparison ( ( "!=" | "==" ) comparison )* ;
comparison -> term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
term -> factor ( ( "-" | "+" ) factor )* ;
factor -> unary ( ( "/" | "*" ) unary )* ;
unary -> ( "!" | "-" ) unary | call ;
call -> primary ( "(" arguments? ")" | "." IDENTIFIER )* ;
primary -> "true" | "false" | "nil" | "this"
| NUMBER | STRING | IDENTIFIER | "(" expression ")"
| "super" "." IDENTIFIER ;
辅助规则(Utility Rules)
为使上面的规则更简洁,部分可复用文法被提取为辅助规则:
function -> IDENTIFIER "(" parameters? ")" block ;
parameters -> IDENTIFIER ( "," IDENTIFIER )* ;
arguments -> expression ( "," expression )* ;
词法文法(Lexical Grammar)
词法文法由扫描器使用,把字符组织成 token。语法文法是上下文无关文法,词法文法则是正则文法:注意其中没有递归规则。
NUMBER -> DIGIT+ ( "." DIGIT+ )? ;
STRING -> "\"" <除 "\"" 外的任意字符>* "\"" ;
IDENTIFIER -> ALPHA ( ALPHA | DIGIT )* ;
ALPHA -> "a" ... "z" | "A" ... "Z" | "_" ;
DIGIT -> "0" ... "9" ;
该文法描述语言的表面结构;例如“this 只能在类中使用”“初始化器不能返回值”“超类必须是类”等约束,由解析后的语义分析与运行时检查负责。