From 70db69ed88fffc09d7778a8af4d8ddc4edffd366 Mon Sep 17 00:00:00 2001 From: jorenchik Date: Sun, 4 Aug 2024 15:06:24 +0300 Subject: [PATCH] Parser refactoring --- src/compiler/compiler.go | 138 +++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 58 deletions(-) diff --git a/src/compiler/compiler.go b/src/compiler/compiler.go index 82938e3..d3c92d6 100644 --- a/src/compiler/compiler.go +++ b/src/compiler/compiler.go @@ -7,7 +7,7 @@ import ( "strings" ) -var automata map[TokenType][]TokenType +type Question interface {} type SingleAnswerQuestion struct { id string; @@ -21,33 +21,41 @@ type Choice struct { isCorrect bool; } -type ChoiceQuestion struct { +type MultipleChoiceQuestion struct { id string; question string; choices []Choice; section string; } -type Question interface {} +type QuestionElement struct { + isDash bool; + content string; +} -func main() { - log.Println("Compilation started") +var automata map[TokenType][]TokenType - file, err := os.ReadFile("/home/jorenchik/Code/mdemory/src/compiler/input.mdem") - if (err != nil) { - log.Fatalf("Cannot open the input file: %s", err.Error()) - return - } - fileContents := string(file) +type CompilerErr struct { + message string; + row int32; + column int32; +} - tokens, err := tokenize([]rune(fileContents)) - if (err != nil) { - fmt.Printf("%s\n", err.Error()) - return - } +func (e CompilerErr) Error() string { + return fmt.Sprintf("%d:%d - %s", e.row, e.column, e.message) +} - // defineParserAutomata - automata = make(map[TokenType][]TokenType) +func contains(s []TokenType, e TokenType) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} + +func parserAutomata() map[TokenType][]TokenType { + automata := make(map[TokenType][]TokenType) automata[TextFragment] = []TokenType{ QuestionEnd, ElementDashStart, ElementPlusStart, SectionIdentifierStart, SectionStart, EOF, SectionEnd, } @@ -82,8 +90,10 @@ func main() { ElementDashStart, SectionIdentifierStart, EOF, } automata[EOF] = []TokenType{} - - // validateGrammar + return automata +} + +func validateGrammar() error { for i := 0; i < len(tokens) - 1; i++ { token := tokens[i] content := token.content @@ -112,16 +122,21 @@ func main() { fmt.Print("\n:") } if (!contains(automata[token.tokenType], nextToken.tokenType)) { - fmt.Printf( - "Token %s cannot precede %s\n", - ToString(&token.tokenType), - ToString(&nextToken.tokenType), - ) - return + return CompilerErr{ + message: fmt.Sprintf( + "Token %s cannot precede %s\n", + ToString(&token.tokenType), + ToString(&nextToken.tokenType), + ), + row: token.row, + column: token.column, + } } } + return nil +} - // extract questions +func ParseQuestions(tokens []Token) ([]Question, error) { questions := []Question{} section := "" i := 0 @@ -152,7 +167,7 @@ func main() { i += 2 } if len(quesitonElements) > 1 { - question := ChoiceQuestion{ + question := MultipleChoiceQuestion{ id: id, question: question, } @@ -192,10 +207,42 @@ func main() { "Not handled: %s", ToString(&tokens[i].tokenType), ) - return + return nil, CompilerErr{ + message: "", + row: tokens[i].row, + column: tokens[i].column, + } } } + return questions, nil +} +func main() { + log.Println("Compilation started") + + file, err := os.ReadFile("/home/jorenchik/Code/mdemory/src/compiler/input.mdem") + if (err != nil) { + log.Fatalf("Cannot open the input file: %s", err.Error()) + return + } + fileContents := string(file) + + tokens, err := tokenize([]rune(fileContents)) + if (err != nil) { + fmt.Printf("%s\n", err.Error()) + return + } + + automata = parserAutomata() + err = validateGrammar() + if (err != nil) { + log.Fatal(err.Error()) + } + + questions, err := ParseQuestions(tokens) + if (err != nil) { + log.Fatal(err.Error()) + } for _, element := range questions { switch element.(type) { case SingleAnswerQuestion: @@ -205,13 +252,13 @@ func main() { strings.Trim(element.(SingleAnswerQuestion).question, "\t\n "), strings.Trim(element.(SingleAnswerQuestion).answer, "\t\n "), ) - case ChoiceQuestion: + case MultipleChoiceQuestion: fmt.Printf( " (%s) %s\n", - element.(ChoiceQuestion).section, - element.(ChoiceQuestion).question, + element.(MultipleChoiceQuestion).section, + element.(MultipleChoiceQuestion).question, ) - for _, el := range element.(ChoiceQuestion).choices { + for _, el := range element.(MultipleChoiceQuestion).choices { opener := '-' if (el.isCorrect) { opener = '+' @@ -223,28 +270,3 @@ func main() { log.Println("Compilation completed") } - -type QuestionElement struct { - isDash bool; - content string; -} - - -type CompilerErr struct { - message string; - row int32; - column int32; -} - -func (e CompilerErr) Error() string { - return fmt.Sprintf("%d:%d - %s", e.row, e.column, e.message) -} - -func contains(s []TokenType, e TokenType) bool { - for _, a := range s { - if a == e { - return true - } - } - return false -}