From 0a09831d174f963ddf3b2f81450342161abb07e7 Mon Sep 17 00:00:00 2001 From: jorenchik Date: Fri, 6 Sep 2024 21:41:19 +0300 Subject: [PATCH] fix parser -> works with multi and single answer question --- src/compiler/lexer/lexer.go | 2 +- src/compiler/parser/parser.go | 75 +++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/compiler/lexer/lexer.go b/src/compiler/lexer/lexer.go index 23cd950..8fb8ee6 100644 --- a/src/compiler/lexer/lexer.go +++ b/src/compiler/lexer/lexer.go @@ -46,7 +46,7 @@ func (token Token) ToString() string { ) } return fmt.Sprintf( - "%s: \"%s\" %d:%d\n", + "%20s: %35s %3d:%3d\n", ToString(&token.TokenType), content, token.Row, diff --git a/src/compiler/parser/parser.go b/src/compiler/parser/parser.go index ed8bda4..cd1b7e3 100644 --- a/src/compiler/parser/parser.go +++ b/src/compiler/parser/parser.go @@ -32,8 +32,10 @@ type MultipleChoiceQuestion struct { func (question SingleAnswerQuestion) ToString() string { return fmt.Sprintf( - " (%s) %s: %s\n", + "%20s: section: %-10s id: %-10s %-30s: %-30s\n", + "", question.Section, + question.ID, strings.Trim(question.Question, "\t\n "), strings.Trim(question.Answer, "\t\n "), ) @@ -42,8 +44,10 @@ func (question SingleAnswerQuestion) ToString() string { func (question MultipleChoiceQuestion) ToString() string { acc := "" acc += fmt.Sprintf( - " (%s) %s\n", + "%20s: section: %-10s id: %-10s %-30s\n", + "", question.section, + question.id, question.question, ) for _, el := range question.choices { @@ -129,7 +133,7 @@ func parserAutomata() map[lexer.TokenType][]lexer.TokenType { func ValidateGrammar(tokens []lexer.Token) error { automata = parserAutomata() - for i := 0; i < len(tokens)-1; i++ { + for i := 0; i < len(tokens) - 1; i++ { token := tokens[i] nextToken := tokens[i+1] if !contains(automata[token.TokenType], nextToken.TokenType) { @@ -171,38 +175,67 @@ func ParseQuestions(fileContents string) ([]Question, error) { if i >= len(tokens) { break } + // - [identifier] question_token > if tokens[i].TokenType == lexer.ElementDashStart { - id := tokens[i+2].Content - question := tokens[i+4].Content - quesitonElements := []QuestionElement{} - i += 6 + var id string + var question string + var questionElements []QuestionElement + + if tokens[i + 1].TokenType == lexer.IdentifierStart { + id = tokens[i + 2].Content + question = tokens[i + 4].Content + questionElements = []QuestionElement{} + i += 6 + } else { + id = "" + question = tokens[i + 1].Content + questionElements = []QuestionElement{} + i += 3 + } + for { - if i+1 >= len(tokens) || - !(tokens[i].TokenType == lexer.ElementDashStart || - tokens[i].TokenType == lexer.ElementPlusStart) || - tokens[i+1].TokenType == lexer.IdentifierStart { - break - } + // Pointer is on the start of an element + // - a_question > + // - [identifier] a_question > + // - an_element + // terminate if we encounter a question. + if i + 3 < len(tokens) && + tokens[i + 3].TokenType != lexer.EOF { + + offset := 0 + if tokens[i + 1].TokenType == lexer.IdentifierStart { + offset = 5 + } else { + offset = 2 + } + if i + offset < len(tokens) && + tokens[i + offset].TokenType == lexer.QuestionEnd { + break + } + } + if (i + 2 >= len(tokens)) { + break; + } questionElement := QuestionElement{} if tokens[i].TokenType == lexer.ElementDashStart { questionElement.isDash = true } else { questionElement.isDash = false } - questionElement.content = tokens[i+1].Content - quesitonElements = append(quesitonElements, questionElement) + questionElement.content = tokens[i + 1].Content + questionElements = append(questionElements, questionElement) i += 2 } - if len(quesitonElements) > 1 { + if len(questionElements) > 1 { question := MultipleChoiceQuestion{ id: id, question: question, } choices := []Choice{} - for k := 0; k < len(quesitonElements); k++ { + for k := 0; k < len(questionElements); k++ { choice := Choice{} - choice.answer = quesitonElements[k].content - choice.isCorrect = !quesitonElements[k].isDash + choice.answer = questionElements[k].content + choice.isCorrect = !questionElements[k].isDash choices = append(choices, choice) } if section != "" { @@ -210,11 +243,11 @@ func ParseQuestions(fileContents string) ([]Question, error) { } question.choices = choices questions = append(questions, question) - } else if len(quesitonElements) == 1 { + } else if len(questionElements) == 1 { question := SingleAnswerQuestion{ ID: id, Question: question, - Answer: quesitonElements[0].content, + Answer: questionElements[0].content, } if section != "" { question.Section = section