fix parser -> works with multi and single answer question

This commit is contained in:
jorenchik
2024-09-06 21:41:19 +03:00
parent 1a2c961807
commit 0a09831d17
2 changed files with 55 additions and 22 deletions

View File

@@ -46,7 +46,7 @@ func (token Token) ToString() string {
) )
} }
return fmt.Sprintf( return fmt.Sprintf(
"%s: \"%s\" %d:%d\n", "%20s: %35s %3d:%3d\n",
ToString(&token.TokenType), ToString(&token.TokenType),
content, content,
token.Row, token.Row,

View File

@@ -32,8 +32,10 @@ type MultipleChoiceQuestion struct {
func (question SingleAnswerQuestion) ToString() string { func (question SingleAnswerQuestion) ToString() string {
return fmt.Sprintf( return fmt.Sprintf(
"<Single choice> (%s) %s: %s\n", "%20s: section: %-10s id: %-10s %-30s: %-30s\n",
"<Single choice>",
question.Section, question.Section,
question.ID,
strings.Trim(question.Question, "\t\n "), strings.Trim(question.Question, "\t\n "),
strings.Trim(question.Answer, "\t\n "), strings.Trim(question.Answer, "\t\n "),
) )
@@ -42,8 +44,10 @@ func (question SingleAnswerQuestion) ToString() string {
func (question MultipleChoiceQuestion) ToString() string { func (question MultipleChoiceQuestion) ToString() string {
acc := "" acc := ""
acc += fmt.Sprintf( acc += fmt.Sprintf(
"<Multi choice> (%s) %s\n", "%20s: section: %-10s id: %-10s %-30s\n",
"<Multi choice>",
question.section, question.section,
question.id,
question.question, question.question,
) )
for _, el := range question.choices { for _, el := range question.choices {
@@ -129,7 +133,7 @@ func parserAutomata() map[lexer.TokenType][]lexer.TokenType {
func ValidateGrammar(tokens []lexer.Token) error { func ValidateGrammar(tokens []lexer.Token) error {
automata = parserAutomata() automata = parserAutomata()
for i := 0; i < len(tokens)-1; i++ { for i := 0; i < len(tokens) - 1; i++ {
token := tokens[i] token := tokens[i]
nextToken := tokens[i+1] nextToken := tokens[i+1]
if !contains(automata[token.TokenType], nextToken.TokenType) { if !contains(automata[token.TokenType], nextToken.TokenType) {
@@ -171,17 +175,46 @@ func ParseQuestions(fileContents string) ([]Question, error) {
if i >= len(tokens) { if i >= len(tokens) {
break break
} }
// - [identifier] question_token >
if tokens[i].TokenType == lexer.ElementDashStart { if tokens[i].TokenType == lexer.ElementDashStart {
id := tokens[i+2].Content var id string
question := tokens[i+4].Content var question string
quesitonElements := []QuestionElement{} var questionElements []QuestionElement
if tokens[i + 1].TokenType == lexer.IdentifierStart {
id = tokens[i + 2].Content
question = tokens[i + 4].Content
questionElements = []QuestionElement{}
i += 6 i += 6
} else {
id = ""
question = tokens[i + 1].Content
questionElements = []QuestionElement{}
i += 3
}
for { for {
if i+1 >= len(tokens) || // Pointer is on the start of an element
!(tokens[i].TokenType == lexer.ElementDashStart || // - a_question >
tokens[i].TokenType == lexer.ElementPlusStart) || // - [identifier] a_question >
tokens[i+1].TokenType == lexer.IdentifierStart { // - 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 break
}
}
if (i + 2 >= len(tokens)) {
break;
} }
questionElement := QuestionElement{} questionElement := QuestionElement{}
if tokens[i].TokenType == lexer.ElementDashStart { if tokens[i].TokenType == lexer.ElementDashStart {
@@ -189,20 +222,20 @@ func ParseQuestions(fileContents string) ([]Question, error) {
} else { } else {
questionElement.isDash = false questionElement.isDash = false
} }
questionElement.content = tokens[i+1].Content questionElement.content = tokens[i + 1].Content
quesitonElements = append(quesitonElements, questionElement) questionElements = append(questionElements, questionElement)
i += 2 i += 2
} }
if len(quesitonElements) > 1 { if len(questionElements) > 1 {
question := MultipleChoiceQuestion{ question := MultipleChoiceQuestion{
id: id, id: id,
question: question, question: question,
} }
choices := []Choice{} choices := []Choice{}
for k := 0; k < len(quesitonElements); k++ { for k := 0; k < len(questionElements); k++ {
choice := Choice{} choice := Choice{}
choice.answer = quesitonElements[k].content choice.answer = questionElements[k].content
choice.isCorrect = !quesitonElements[k].isDash choice.isCorrect = !questionElements[k].isDash
choices = append(choices, choice) choices = append(choices, choice)
} }
if section != "" { if section != "" {
@@ -210,11 +243,11 @@ func ParseQuestions(fileContents string) ([]Question, error) {
} }
question.choices = choices question.choices = choices
questions = append(questions, question) questions = append(questions, question)
} else if len(quesitonElements) == 1 { } else if len(questionElements) == 1 {
question := SingleAnswerQuestion{ question := SingleAnswerQuestion{
ID: id, ID: id,
Question: question, Question: question,
Answer: quesitonElements[0].content, Answer: questionElements[0].content,
} }
if section != "" { if section != "" {
question.Section = section question.Section = section