Frontend and communication

This commit is contained in:
jorenchik
2024-09-01 10:53:46 +03:00
parent e824115fae
commit ebdb5bed62
11 changed files with 463 additions and 227 deletions

View File

@@ -2,44 +2,44 @@ package parser
import (
"fmt"
"strings"
"log"
"github.com/jorenchik/mdemory/src/compiler/lexer"
"log"
"strings"
)
type Question interface {
ToString() string;
ToString() string
}
type SingleAnswerQuestion struct {
id string;
question string;
answer string;
section string;
ID string
Question string
Answer string
Section string
}
type Choice struct {
answer string;
isCorrect bool;
answer string
isCorrect bool
}
type MultipleChoiceQuestion struct {
id string;
question string;
choices []Choice;
section string;
id string
question string
choices []Choice
section string
}
func (question SingleAnswerQuestion)ToString() string {
func (question SingleAnswerQuestion) ToString() string {
return fmt.Sprintf(
"<Single choice> (%s) %s: %s\n",
question.section,
strings.Trim(question.question, "\t\n "),
strings.Trim(question.answer, "\t\n "),
question.Section,
strings.Trim(question.Question, "\t\n "),
strings.Trim(question.Answer, "\t\n "),
)
}
func (question MultipleChoiceQuestion)ToString() string {
func (question MultipleChoiceQuestion) ToString() string {
acc := ""
acc += fmt.Sprintf(
"<Multi choice> (%s) %s\n",
@@ -48,7 +48,7 @@ func (question MultipleChoiceQuestion)ToString() string {
)
for _, el := range question.choices {
opener := '-'
if (el.isCorrect) {
if el.isCorrect {
opener = '+'
}
acc += fmt.Sprintf("\t%c %s\n", opener, strings.Trim(el.answer, "\t\n "))
@@ -57,16 +57,16 @@ func (question MultipleChoiceQuestion)ToString() string {
}
type QuestionElement struct {
isDash bool;
content string;
}
isDash bool
content string
}
var automata map[lexer.TokenType][]lexer.TokenType
var automata map[lexer.TokenType][]lexer.TokenType
type CompilerErr struct {
message string;
row int32;
column int32;
message string
row int32
column int32
}
func (e CompilerErr) Error() string {
@@ -74,12 +74,12 @@ func (e CompilerErr) Error() string {
}
func contains(s []lexer.TokenType, e lexer.TokenType) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
for _, a := range s {
if a == e {
return true
}
}
return false
}
func parserAutomata() map[lexer.TokenType][]lexer.TokenType {
@@ -95,22 +95,22 @@ func parserAutomata() map[lexer.TokenType][]lexer.TokenType {
}
automata[lexer.QuestionEnd] = []lexer.TokenType{
lexer.ElementDashStart, lexer.ElementPlusStart,
}
}
automata[lexer.ElementDashStart] = []lexer.TokenType{
lexer.IdentifierStart, lexer.TextFragment,
}
}
automata[lexer.ElementPlusStart] = []lexer.TokenType{
lexer.TextFragment,
}
}
automata[lexer.Identifier] = []lexer.TokenType{
lexer.IdentifierEnd, lexer.SectionStart,
}
}
automata[lexer.IdentifierStart] = []lexer.TokenType{
lexer.Identifier,
}
}
automata[lexer.IdentifierEnd] = []lexer.TokenType{
lexer.TextFragment,
}
}
automata[lexer.SectionIdentifierStart] = []lexer.TokenType{
lexer.Identifier,
}
@@ -129,30 +129,30 @@ 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)) {
nextToken := tokens[i+1]
if !contains(automata[token.TokenType], nextToken.TokenType) {
return CompilerErr{
message: fmt.Sprintf(
"Token %s cannot precede %s\n",
lexer.ToString(&token.TokenType),
lexer.ToString(&nextToken.TokenType),
),
row: token.Row,
row: token.Row,
column: token.Column,
}
}
}
}
return nil
}
func ParseQuestions(fileContents string) ([]Question, error) {
tokens, err := lexer.TokenizeMdem([]rune(fileContents))
if (err != nil) {
if err != nil {
return nil, err
}
if (true) {
if true {
log.Println("Lexer output:")
for _, el := range tokens {
fmt.Print(el.ToString())
@@ -160,7 +160,7 @@ func ParseQuestions(fileContents string) ([]Question, error) {
}
err = ValidateGrammar(tokens)
if (err != nil) {
if err != nil {
log.Fatal(err.Error())
}
@@ -168,26 +168,26 @@ func ParseQuestions(fileContents string) ([]Question, error) {
section := ""
i := 0
for {
if (i >= len(tokens)) {
if i >= len(tokens) {
break
}
if (tokens[i].TokenType == lexer.ElementDashStart) {
id := tokens[i + 2].Content
question := tokens[i + 4].Content
if tokens[i].TokenType == lexer.ElementDashStart {
id := tokens[i+2].Content
question := tokens[i+4].Content
quesitonElements := []QuestionElement{}
i += 6
for {
if (i + 1 >= len(tokens) ||
if i+1 >= len(tokens) ||
!(tokens[i].TokenType == lexer.ElementDashStart ||
tokens[i].TokenType == lexer.ElementPlusStart) ||
tokens[i+1].TokenType == lexer.IdentifierStart) {
tokens[i+1].TokenType == lexer.IdentifierStart {
break
}
questionElement := QuestionElement{}
if (tokens[i].TokenType == lexer.ElementDashStart) {
questionElement.isDash = true
if tokens[i].TokenType == lexer.ElementDashStart {
questionElement.isDash = true
} else {
questionElement.isDash = false
questionElement.isDash = false
}
questionElement.content = tokens[i+1].Content
quesitonElements = append(quesitonElements, questionElement)
@@ -195,7 +195,7 @@ func ParseQuestions(fileContents string) ([]Question, error) {
}
if len(quesitonElements) > 1 {
question := MultipleChoiceQuestion{
id: id,
id: id,
question: question,
}
choices := []Choice{}
@@ -204,30 +204,30 @@ func ParseQuestions(fileContents string) ([]Question, error) {
choice.answer = quesitonElements[k].content
choice.isCorrect = !quesitonElements[k].isDash
choices = append(choices, choice)
}
if (section != "") {
}
if section != "" {
question.section = section
}
question.choices = choices
questions = append(questions, question)
} else if (len(quesitonElements) == 1) {
} else if len(quesitonElements) == 1 {
question := SingleAnswerQuestion{
id: id,
question: question,
answer: quesitonElements[0].content,
ID: id,
Question: question,
Answer: quesitonElements[0].content,
}
if (section != "") {
question.section = section
if section != "" {
question.Section = section
}
questions = append(questions, question)
}
} else if (tokens[i].TokenType == lexer.SectionIdentifierStart) {
section = tokens[i + 1].Content
i += 3;
} else if (tokens[i].TokenType == lexer.SectionEnd) {
} else if tokens[i].TokenType == lexer.SectionIdentifierStart {
section = tokens[i+1].Content
i += 3
} else if tokens[i].TokenType == lexer.SectionEnd {
section = ""
i += 1
} else if (tokens[i].TokenType == lexer.EOF) {
} else if tokens[i].TokenType == lexer.EOF {
break
} else {
log.Fatalf(
@@ -236,8 +236,8 @@ func ParseQuestions(fileContents string) ([]Question, error) {
)
return nil, CompilerErr{
message: "",
row: tokens[i].Row,
column: tokens[i].Column,
row: tokens[i].Row,
column: tokens[i].Column,
}
}
}