diff --git a/src/utils/latl/grammar.js b/src/utils/latl/grammar.js index 0475672..9f6ba68 100644 --- a/src/utils/latl/grammar.js +++ b/src/utils/latl/grammar.js @@ -6,7 +6,7 @@ function id(x) { return x[0]; } const { lexer } = require('./lexer.js'); const getTerminal = d => d ? d[0] : null; const getAll = d => d.map((item, i) => ({ [i]: item })); - const flag = token => d => d.map(item => ({ [token]: clearNull(item) })) + const flag = token => d => d.map(item => ({ [token]: item })) const clearNull = d => d.filter(t => !!t && (t.length !== 1 || t[0])).map(t => t.length ? clearNull(t) : t); const flagIndex = d => d.map((item, i) => ({[i]: item})) const remove = _ => null; @@ -35,22 +35,21 @@ var grammar = { {"name": "_", "symbols": ["_$ebnf$1"], "postprocess": remove}, {"name": "__", "symbols": [(lexer.has("whiteSpace") ? {type: "whiteSpace"} : whiteSpace)], "postprocess": remove}, {"name": "statement", "symbols": ["comment"]}, - {"name": "statement", "symbols": ["definition"], "postprocess": pipe(getTerminal, clearNull)}, + {"name": "statement", "symbols": ["definition"], "postprocess": pipe(getTerminal)}, {"name": "comment", "symbols": [(lexer.has("comment") ? {type: "comment"} : comment)], "postprocess": pipe(getTerminal, remove)}, - {"name": "definition", "symbols": [(lexer.has("kwSet") ? {type: "kwSet"} : kwSet), "__", "setDefinition"], "postprocess": d => ({token: d[0].type, [d[0].value]: d[2]})}, + {"name": "definition", "symbols": [(lexer.has("kwSet") ? {type: "kwSet"} : kwSet), "__", "setDefinition"], "postprocess": d => ({[d[0].value]: d[2]})}, {"name": "setDefinition$ebnf$1", "symbols": []}, {"name": "setDefinition$ebnf$1$subexpression$1", "symbols": [(lexer.has("setIdentifier") ? {type: "setIdentifier"} : setIdentifier), "__", (lexer.has("equal") ? {type: "equal"} : equal), "__", "setExpression", (lexer.has("comma") ? {type: "comma"} : comma), "__"]}, {"name": "setDefinition$ebnf$1", "symbols": ["setDefinition$ebnf$1", "setDefinition$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, - {"name": "setDefinition", "symbols": ["setDefinition$ebnf$1", (lexer.has("setIdentifier") ? {type: "setIdentifier"} : setIdentifier), "__", (lexer.has("equal") ? {type: "equal"} : equal), "__", "setExpression"]}, - {"name": "setExpression", "symbols": [(lexer.has("openSquareBracket") ? {type: "openSquareBracket"} : openSquareBracket), "_", "phoneList", "_", (lexer.has("closeSquareBracket") ? {type: "closeSquareBracket"} : closeSquareBracket)], "postprocess": d => d.filter(t => t && t.length)}, + {"name": "setDefinition", "symbols": ["setDefinition$ebnf$1", (lexer.has("setIdentifier") ? {type: "setIdentifier"} : setIdentifier), "__", (lexer.has("equal") ? {type: "equal"} : equal), "__", "setExpression"], "postprocess": d => { + if (d.type === 'setIdentifier') return { setIdentifier: d.value } + return d + } }, + {"name": "setExpression", "symbols": [(lexer.has("openSquareBracket") ? {type: "openSquareBracket"} : openSquareBracket), "_", "phoneList", "_", (lexer.has("closeSquareBracket") ? {type: "closeSquareBracket"} : closeSquareBracket)]}, {"name": "phoneList$ebnf$1", "symbols": []}, {"name": "phoneList$ebnf$1$subexpression$1", "symbols": [(lexer.has("phone") ? {type: "phone"} : phone), (lexer.has("comma") ? {type: "comma"} : comma), "_"]}, {"name": "phoneList$ebnf$1", "symbols": ["phoneList$ebnf$1", "phoneList$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, - {"name": "phoneList", "symbols": ["phoneList$ebnf$1", (lexer.has("phone") ? {type: "phone"} : phone)], "postprocess": d => d.filter(t => t && (t.type === 'phone' || t[0]) ) - .flatMap(t => { - if (!t.length) return t; - return t[0].filter(st => st && st.type === 'phone') - }) } + {"name": "phoneList", "symbols": ["phoneList$ebnf$1", (lexer.has("phone") ? {type: "phone"} : phone)], "postprocess": pipe(d => d ? d.toString() : d)} ] , ParserStart: "main" } diff --git a/src/utils/latl/grammar.ne b/src/utils/latl/grammar.ne index bd92e93..fbb5cc8 100644 --- a/src/utils/latl/grammar.ne +++ b/src/utils/latl/grammar.ne @@ -2,7 +2,7 @@ const { lexer } = require('./lexer.js'); const getTerminal = d => d ? d[0] : null; const getAll = d => d.map((item, i) => ({ [i]: item })); - const flag = token => d => d.map(item => ({ [token]: clearNull(item) })) + const flag = token => d => d.map(item => ({ [token]: item })) const clearNull = d => d.filter(t => !!t && (t.length !== 1 || t[0])).map(t => t.length ? clearNull(t) : t); const flagIndex = d => d.map((item, i) => ({[i]: item})) const remove = _ => null; @@ -32,24 +32,25 @@ __ -> %whiteSpace {% remove %} statement -> comment | definition - {% pipe(getTerminal, clearNull) %} + {% pipe(getTerminal) %} comment -> %comment {% pipe(getTerminal, remove) %} # SETS definition -> %kwSet __ setDefinition - {% d => ({token: d[0].type, [d[0].value]: d[2]}) %} + {% d => ({[d[0].value]: d[2]}) %} setDefinition -> (%setIdentifier __ %equal __ setExpression %comma __):* %setIdentifier __ %equal __ setExpression - # {% pipe( - # //constructSet, - # getTerminal) %} + {% d => { + if (d.type === 'setIdentifier') return { setIdentifier: d.value } + return d + } %} setExpression -> %openSquareBracket _ phoneList _ %closeSquareBracket - {% d => d.filter(t => t && t.length) %} + # {% pipe(d => d.filter(t => t && t.length)) %} phoneList -> (%phone %comma _):* %phone - # {% clearNull %} - {% d => d.filter(t => t && (t.type === 'phone' || t[0]) ) - .flatMap(t => { - if (!t.length) return t; - return t[0].filter(st => st && st.type === 'phone') - }) %} + {% pipe(d => d ? d.toString() : d) %} + # {% d => d.filter(t => t && (t.type === 'phone' || t[0]) ) + # .flatMap(t => { + # if (!t.length) return t; + # return t[0].filter(st => st && st.type === 'phone') + # }) %} diff --git a/src/utils/latl/test/assertionData.js b/src/utils/latl/test/assertionData.js index c654048..174efff 100644 --- a/src/utils/latl/test/assertionData.js +++ b/src/utils/latl/test/assertionData.js @@ -4,6 +4,9 @@ export const assertionData = { tokens: [ { type: 'comment', value: '; comment'} ], + AST: { + main: [] + }, code: '' }, simpleSetDefinition: { @@ -12,7 +15,8 @@ export const assertionData = { { type: 'kwSet', value: 'set' }, { type: 'whiteSpace', value: ' ' }, { type: 'setIdentifier', value: 'PLOSIVES' } - ] + ], + code: '' }, commaSetDefinition: { latl: ` @@ -129,7 +133,21 @@ set NASAL_PULMONIC_CONSONANTS = [ m̥, m, ɱ, n̼, n̥, n, ɳ̊, { type: 'phone', value: 'ʔ' }, { type: 'whiteSpace', value: ' ' }, { type: 'closeSquareBracket', value: ']' } - ] + ], + AST: { + main: [ + { + set: { + setIdentifier: 'NASAL_PULMONIC_CONSONANTS', + items: [ 'm̥', 'm', 'ɱ', 'n̼', 'n̥', 'n', 'ɳ̊', 'ɳ', 'ɲ̊', 'ɲ', `ŋ`, ' ̊ŋ', 'ɴ' ] + }, + set: { + setIdentifier: 'STOP_PULMONIC_CONSONANTS', + items: [ 'p', 'b', 'p̪', 'b̪', 't̼', 'd̼', 't', 'd', 'ʈ', 'ɖ', 'c', 'ɟ', 'k', 'ɡ', 'q', 'ɢ', 'ʡ', 'ʔ' ] + } + } + ] + } }, setAliasDefinition: { latl: ` diff --git a/src/utils/latl/test/codeGenerator.test.js b/src/utils/latl/test/codeGenerator.test.js index 30516d4..159451d 100644 --- a/src/utils/latl/test/codeGenerator.test.js +++ b/src/utils/latl/test/codeGenerator.test.js @@ -3,10 +3,8 @@ import { codeGenerator } from '../codeGenerator'; describe('codeGenerator', () => { it('parses simple comment', () => { - const { latl } = assertionData.simpleComment; - const code = codeGenerator(latl) - // expect(AST.length).toBe(1); - // expect(AST[0]).toStrictEqual({ main: [ ]}) - console.log(code) - }) + const { latl, code } = assertionData.simpleComment; + const generatedCode = codeGenerator(latl); + expect(generatedCode).toEqual(code); + }); }) \ No newline at end of file diff --git a/src/utils/latl/test/parser.test.js b/src/utils/latl/test/parser.test.js index 1813b43..89bb518 100644 --- a/src/utils/latl/test/parser.test.js +++ b/src/utils/latl/test/parser.test.js @@ -4,17 +4,18 @@ import { assertionData } from './assertionData'; describe('parser', () => { it('parses simple comment', () => { - const { latl } = assertionData.simpleComment; - const AST = parser().feed(latl).results; - expect(AST.length).toBe(1); - expect(AST[0]).toStrictEqual({ main: [ ]}) + const { latl, AST } = assertionData.simpleComment; + const feedResults = parser().feed(latl).results; + expect(feedResults.length).toBe(1); + expect(feedResults[0]).toStrictEqual(AST) }) - // it('parses multiple set definitions with comma operator', () => { - // const { latl } = assertionData.commaSetDefinition; - // const AST = parser().feed(latl).results; - // console.log(AST[0]) - // }); + it('parses multiple set definitions with comma operator', () => { + const { latl, AST } = assertionData.commaSetDefinition; + const feedResults = parser().feed(latl).results; + expect(feedResults.length).toBe(1); + expect(feedResults[0]).toStrictEqual(AST); + }); // it('lexes set definition with alias', () => { // const { latl, tokens } = assertionData.setAliasDefinition; @@ -46,3 +47,118 @@ describe('parser', () => { // expect(stream).toStrictEqual(tokens); // }) }) + +// { +// "set": +// [ +// [ +// [ +// { +// "col": 5, +// "line": 2, +// "lineBreaks": 0, +// "offset": 5, +// "text": "NASAL_PULMONIC_CONSONANTS", +// "toString": [tokenToString], +// "type": "setIdentifier", +// "value": "NASAL_PULMONIC_CONSONANTS", +// }, +// null, +// { +// "col": 45, +// "line": 2, +// "lineBreaks": 0, +// "offset": 45, +// "text": "=", +// "toString": [tokenToString], +// "type": "equal", +// "value": "=", +// }, +// null, +// [ +// [ +// { +// "col": 49, +// "line": 2, +// "lineBreaks": 0, +// "offset": 49, +// "text": "m̥", +// "toString": [tokenToString], +// "type": "phone", +// "value": "m̥", +// }, +// { +// "col": 91, +// "line": 2, +// "lineBreaks": 0, +// "offset": 91, +// "text": "ɴ", +// "toString": [tokenToString], +// "type": "phone", +// "value": "ɴ", +// }, +// ], +// ], +// { +// "col": 94, +// "line": 2, +// "lineBreaks": 0, +// "offset": 94, +// "text": ",", +// "toString": [tokenToString], +// "type": "comma", +// "value": ",", +// }, +// null, +// ], +// ], +// - "setIdentifier": "STOP_PULMONIC_CONSONANTS", +// { +// "col": 5, +// "line": 3, +// "lineBreaks": 0, +// "offset": 100, +// "text": "STOP_PULMONIC_CONSONANTS", +// "toString": [tokenToString], +// "type": "setIdentifier", +// "value": "STOP_PULMONIC_CONSONANTS", +// }, +// null, +// { +// "col": 45, +// "line": 3, +// "lineBreaks": 0, +// "offset": 140, +// "text": "=", +// "toString": [tokenToString], +// "type": "equal", +// "value": "=", +// }, +// null, +// [ +// [ +// { +// "col": 49, +// "line": 3, +// "lineBreaks": 0, +// "offset": 144, +// "text": "p", +// "toString": [tokenToString], +// "type": "phone", +// "value": "p", +// }, +// { +// "col": 104, +// "line": 3, +// "lineBreaks": 0, +// "offset": 199, +// "text": "ʔ", +// "toString": [tokenToString], +// "type": "phone", +// "value": "ʔ", +// }, +// ], +// ], +// ], +// "token": "kwSet", +// } \ No newline at end of file