编译原理
stateDiagram-v2 源代码 --> 词法分析 state 前端 { 词法分析 --> 语法分析 语法分析 --> 语义分析 } 语义分析 --> 生成中间代码 state 后端 { 生成中间代码 --> 优化 优化 --> 生成目标代码 }
词法分析
有限自动机
要实现一个词法分析器,首先需要写出每个词法的正则表达式,并画出有限自动机,之后,只要用代码表示这种状态迁移过程就可以了
age >= 45 的此法解析自动机:
stateDiagram-v2 初始 --> 比较操作符>: > 比较操作符> --> 比较操作符>=: = 初始 --> ID: 字母 ID --> ID: 字母或数字 初始 --> 数字字面量: 数字 数字字面量 --> 数字字面量: 数字
DfaState newState = DfaState.Initial;if (isAlpha(ch)) { //第一个字符是字母 newState = DfaState.Id; //进入Id状态 token.type = TokenType.Identifier; tokenText.append(ch);} else if (isDigit(ch)) { //第一个字符是数字 newState = DfaState.IntLiteral; token.type = TokenType.IntLiteral; tokenText.append(ch);} else if (ch == '>') { //第一个字符是> newState = DfaState.GT; token.type = TokenType.GT; tokenText.append(ch);}
使用正则表达式描述词法:
Id : [a-zA-Z_] ([a-zA-Z_] | [0-9])*IntLiteral: [0-9]+GT : '>'GE : '>='
语法分析
语法规则描述
BNF:
add ::= mul | add + mulmul ::= pri | mul * pripri ::= Id | Num | (add)
扩展BNF(EBNF):
// 会用到类似正则表达式的一些写法add -> mul (+ mul)*
上下文无关文法
上下文无关指的是无论在任何情况下,文法的推导规则都是一样的
描述整数加法与乘法的文法,在解析后,可以形成一颗AST:
additiveExpression : multiplicativeExpression | additiveExpression Plus multiplicativeExpression ;multiplicativeExpression : IntLiteral | multiplicativeExpression Star IntLiteral ;
“2+3*5” 的推导过程:
-->additiveExpression + multiplicativeExpression-->multiplicativeExpression + multiplicativeExpression-->IntLiteral + multiplicativeExpression-->IntLiteral + multiplicativeExpression * IntLiteral -->IntLiteral + IntLiteral * IntLiteral
递归下降
上级文法嵌套下级文法,上级的算法调用下级的算法
消除左递归:
对于加法与乘法的文法:
add -> mul | add + mul
会陷入无限递归,那就引入一个终止条件,也就是空集来终止递归:
add -> mul add'add' -> + mul add' | ε
// EBNP表达add -> mul (+ mul)*
Antlr
词法规则文件:
lexer grammar Hello; //lexer关键字意味着这是一个词法规则文件,要与文件名相同。@header {package antlrtest;}//关键字If : 'if' | '如果'; //可以在程序里用‘如果’来代替'if'Int : 'int';//常量IntLiteral: [0-9]+;StringLiteral: '"' .*? '"' ; //字符串常量//操作符AssignmentOP: '=' ; RelationalOP: '=='|'>'|'>='|'<' |'<=' ; Star: '*';Plus: '+';Sharp: '#';SemiColon: ';';Dot: '.';Comm: ',';LeftBracket : '[';RightBracket: ']';LeftBrace: '{';RightBrace: '}';LeftParen: '(';RightParen: ')';//标识符Id : [a-zA-Z_] ([a-zA-Z_] | [0-9])*;//空白字符,抛弃Whitespace: [ \t]+ -> skip;Newline: ( '\r' '\n'?|'\n')-> skip;
// 语法分析器expression : assignmentExpression | expression ',' assignmentExpression ;assignmentExpression : additiveExpression | Identifier assignmentOperator additiveExpression ;assignmentOperator : '=' | '*=' | '/=' | '%=' | '+=' | '-=' ;additiveExpression : multiplicativeExpression | additiveExpression '+' multiplicativeExpression | additiveExpression '-' multiplicativeExpression ;multiplicativeExpression : primaryExpression | multiplicativeExpression '*' primaryExpression | multiplicativeExpression '/' primaryExpression | multiplicativeExpression '%' primaryExpression ;
# 生成词法分析器的java源码antlr Hello.g4# 生成语法分析器antlr PlayScript.g4# 输入表达式查看ASTgrun antlrtest.PlayScript expression -gui