面试题答案
一键面试Go语言关键字
Go语言有25个关键字:
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
词法分析阶段关键字和操作符区分解析
在词法分析阶段,词法分析器按字符流顺序读取输入源程序。它依据预先定义的规则,通过状态转移方式识别记号(token)。对于关键字和操作符:
- 关键字:词法分析器有一张关键字表。当从输入流读取字符并形成一个标识符形式的字符串时,会将该字符串与关键字表进行匹配。如果匹配成功,则识别为关键字;否则为普通标识符。
- 操作符:操作符有固定的字符模式,词法分析器根据操作符的字符序列模式来识别。例如,单个字符的操作符(如
+
、-
、*
、/
),以及多个字符组成的操作符(如+=
、++
、==
等)。当读取到这些特定字符组合时,就识别为相应的操作符。
简单词法分析器设计实现
设计一个简单词法分析器识别关键字和操作符,可以按以下步骤:
- 定义记号类型:
type TokenType int
const (
TokenEOF TokenType = iota
TokenKeyword
TokenOperator
TokenIdentifier
TokenError
)
- 定义记号结构体:
type Token struct {
Type TokenType
Value string
}
- 初始化关键字表:
var keywordMap = map[string]bool{
"break": true,
"default": true,
"func": true,
// 其它关键字
}
- 实现词法分析函数:
func Lexer(input string) ([]Token, error) {
var tokens []Token
i := 0
for i < len(input) {
switch {
case isWhitespace(input[i]):
i++
case isLetter(input[i]):
start := i
for i < len(input) && (isLetter(input[i]) || isDigit(input[i])) {
i++
}
tokenStr := input[start:i]
if keywordMap[tokenStr] {
tokens = append(tokens, Token{Type: TokenKeyword, Value: tokenStr})
} else {
tokens = append(tokens, Token{Type: TokenIdentifier, Value: tokenStr})
}
case isOperatorChar(input[i]):
start := i
for i < len(input) && isOperatorChar(input[i+1]) && isOperator(input[start:i+2]) {
i++
}
tokens = append(tokens, Token{Type: TokenOperator, Value: input[start:i+1]})
i++
default:
return nil, fmt.Errorf("unexpected character: %c", input[i])
}
}
tokens = append(tokens, Token{Type: TokenEOF, Value: ""})
return tokens, nil
}
func isWhitespace(c byte) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
func isLetter(c byte) bool {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
}
func isDigit(c byte) bool {
return c >= '0' && c <= '9'
}
func isOperatorChar(c byte) bool {
return strings.ContainsAny(string(c), "+-*/%&|^<>!=")
}
func isOperator(s string) bool {
operators := []string{"+", "-", "*", "/", "%", "&", "|", "^", "<", ">", "!", "=",
"++", "--", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<", ">>", "==", "!=", "<=", ">="}
for _, op := range operators {
if op == s {
return true
}
}
return false
}
通过上述设计,词法分析器可以将输入字符串解析为关键字、操作符等记号序列。