Skip to main content

附录 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 只能在类中使用”“初始化器不能返回值”“超类必须是类”等约束,由解析后的语义分析与运行时检查负责。