Я пишу парсер рекурсивного спуска на Go для простого выдуманного языка, поэтому я создаю грамматику по ходу дела. Мой синтаксический анализатор работает, но я хотел спросить, есть ли какие-либо рекомендации относительно того, как я должен выложить свой код или когда я должен поместить код в его собственную функцию и т. Д., Чтобы сделать его более читабельным.
I 'мы создавали парсер, следуя простым правилам, которые я выучил до сих пор, т.е. каждый нетерминал - это своя собственная функция, хотя мой код работает, я думаю, он выглядит очень грязно и нечитабельно.
Я включил код для нетерминального присваивания и грамматику над функцией.
Я взял большую часть обработки ошибок, чтобы уменьшить размер функции.
Вот несколько примеров того, что этот код может анализировать:
a = 10
a,b,c = 1,2,3
a int = 100
a,b string = "hello", "world"
Может кто-нибудь дать мне несколько советово том, как я могу сделать свой код более читабельным, пожалуйста?
// assignment : variable_list '=' expr_list
// | variable_list type
// | variable_list type '=' expr_list
func (p *Parser) assignment() ast.Noder {
assignment := &ast.AssignmentNode{}
assignment.Left = p.variable_list()
// This if-statement deals with rule 2 or 3
if p.currentToken.Type != token.ASSIGN {
// Static variable declaration
// Could be a declaration or an assignment
// Only static variables can be declared without providing a value
assignment.IsStatic = true
assignment.Type = p.var_type().Value
assignment.Right = nil
p.nextToken()
// Rule 2 is finished at this point in the code
// This if-statement is for rule 3
if p.currentToken.Type == token.ASSIGN {
assignment.Operator = p.currentToken
p.nextToken()
assignment.Right = p.expr_list()
}
} else {
// This deals with rule 1
assignment.Operator = p.currentToken
p.nextToken()
assignment.Right = p.expr_list()
}
if assignment.Right == nil {
for i := 0; i < len(assignment.Left); i++ {
assignment.Right = append(assignment.Right, nil)
}
}
if len(assignment.Left) != len(assignment.Right) {
p.FoundError(p.syntaxError("variable mismatch, " + strconv.Itoa(len(assignment.Left)) + " on left but " + strconv.Itoa(len(assignment.Right)) + " on right,"))
}
return assignment
}