diff --git a/src/utils/latl/grammar.js b/src/utils/latl/grammar.js index cceab65..92e653a 100644 --- a/src/utils/latl/grammar.js +++ b/src/utils/latl/grammar.js @@ -25,8 +25,10 @@ var grammar = { {"name": "main$ebnf$1$subexpression$1", "symbols": ["_", "statement"]}, {"name": "main$ebnf$1", "symbols": ["main$ebnf$1", "main$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "main", "symbols": ["main$ebnf$1", "_"], "postprocess": pipe( - getTerminal, clearNull, + // recursive call to fix repeat? + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), flag('main'), getTerminal, ) }, @@ -38,26 +40,36 @@ var grammar = { {"name": "equal", "symbols": [(lexer.has("equal") ? {type: "equal"} : equal)], "postprocess": remove}, {"name": "statement", "symbols": ["comment"]}, {"name": "statement", "symbols": ["definition"], "postprocess": pipe( - objFromArr + d => d.flatMap(u => u && u.length ? u.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet') : u), + // recursive call to fit repeat? + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), + // may split from other definition statements + d => d.map(t => t && t.length > 1 ? ({ type: 'set', ...objFromArr(t) }) : null) ) }, {"name": "comment", "symbols": [(lexer.has("comment") ? {type: "comment"} : comment)], "postprocess": pipe(getTerminal, remove)}, - {"name": "definition", "symbols": [(lexer.has("kwSet") ? {type: "kwSet"} : kwSet), "__", "setDefinition"], "postprocess": pipe( - d => ({[d[0].value]: objFromArr(d[2]) }), + {"name": "definition$ebnf$1", "symbols": []}, + {"name": "definition$ebnf$1$subexpression$1", "symbols": ["setDefinition", (lexer.has("comma") ? {type: "comma"} : comma), "__"]}, + {"name": "definition$ebnf$1", "symbols": ["definition$ebnf$1", "definition$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, + {"name": "definition", "symbols": [(lexer.has("kwSet") ? {type: "kwSet"} : kwSet), "__", "definition$ebnf$1", "setDefinition"], "postprocess": pipe( + // not yet sure why this call is required twice + d => d.map(u => u && u.length ? u.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet') : u), + d => d.map(u => u && u.length ? u.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet') : u), + d => d.map(u => u && u.length ? u.map(v => v.length ? v.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet')[0] : v) : u), + clearNull, ) }, - {"name": "setDefinition$ebnf$1", "symbols": []}, - {"name": "setDefinition$ebnf$1$subexpression$1", "symbols": [(lexer.has("setIdentifier") ? {type: "setIdentifier"} : setIdentifier), "__", "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), "__", "equal", "__", "setExpression"], "postprocess": + {"name": "setDefinition", "symbols": [(lexer.has("setIdentifier") ? {type: "setIdentifier"} : setIdentifier), "__", "equal", "__", "setExpression"], "postprocess": pipe( d => d.filter(t => !!t && t.length !== 0), d => d.map(t => t.type === 'setIdentifier' ? { setIdentifier: t.toString() } : t), - d => d.map(t => t && t.length && t[0].hasOwnProperty('setExpression') ? t[0] : t) + d => d.map(t => t && t.length && t[0].hasOwnProperty('setExpression') ? t[0] : t), ) }, {"name": "setExpression", "symbols": [(lexer.has("openSquareBracket") ? {type: "openSquareBracket"} : openSquareBracket), "_", "phoneList", "_", (lexer.has("closeSquareBracket") ? {type: "closeSquareBracket"} : closeSquareBracket)], "postprocess": pipe( - d => d.filter(t => t && t.length), - d => d.map(t => t.map(u => u[0])), + // filters commas and whitespace + d => d.filter(t => t && t.length), + d => d.map(t => t.map(u => u[0])), flag('setExpression') ) }, {"name": "phoneList$ebnf$1", "symbols": []}, diff --git a/src/utils/latl/grammar.ne b/src/utils/latl/grammar.ne index 1fd3f1b..cdbf5e0 100644 --- a/src/utils/latl/grammar.ne +++ b/src/utils/latl/grammar.ne @@ -20,8 +20,10 @@ main -> (_ statement):* _ {% pipe( - getTerminal, clearNull, + // recursive call to fix repeat? + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), flag('main'), getTerminal, ) %} @@ -37,31 +39,40 @@ equal -> %equal statement -> comment | definition {% pipe( - objFromArr + d => d.flatMap(u => u && u.length ? u.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet') : u), + // recursive call to fit repeat? + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), + d => d.map(t => t && t.length === 1 && t[0] ? t[0] : t), + // may split from other definition statements + d => d.map(t => t && t.length > 1 ? ({ type: 'set', ...objFromArr(t) }) : null) ) %} comment -> %comment {% pipe(getTerminal, remove) %} # SETS -definition -> %kwSet __ setDefinition +definition -> %kwSet __ (setDefinition %comma __):* setDefinition {% pipe( - d => ({[d[0].value]: objFromArr(d[2]) }), + // not yet sure why this call is required twice + d => d.map(u => u && u.length ? u.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet') : u), + d => d.map(u => u && u.length ? u.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet') : u), + d => d.map(u => u && u.length ? u.map(v => v.length ? v.filter(t => t && t.type !== 'comma' && t.type !== 'kwSet')[0] : v) : u), + clearNull, ) %} - # {% flag('definition') %} -setDefinition -> (%setIdentifier __ equal __ setExpression %comma __):* %setIdentifier __ equal __ setExpression +setDefinition -> %setIdentifier __ equal __ setExpression {% pipe( d => d.filter(t => !!t && t.length !== 0), d => d.map(t => t.type === 'setIdentifier' ? { setIdentifier: t.toString() } : t), - d => d.map(t => t && t.length && t[0].hasOwnProperty('setExpression') ? t[0] : t) + d => d.map(t => t && t.length && t[0].hasOwnProperty('setExpression') ? t[0] : t), ) %} setExpression -> %openSquareBracket _ phoneList _ %closeSquareBracket {% pipe( - d => d.filter(t => t && t.length), - d => d.map(t => t.map(u => u[0])), + // filters commas and whitespace + d => d.filter(t => t && t.length), + d => d.map(t => t.map(u => u[0])), flag('setExpression') ) %} phoneList -> (%phone (%comma _):* ):* diff --git a/src/utils/latl/test/assertionData.js b/src/utils/latl/test/assertionData.js index fedfa8c..f80be9a 100644 --- a/src/utils/latl/test/assertionData.js +++ b/src/utils/latl/test/assertionData.js @@ -33,10 +33,9 @@ export const assertionData = { AST: { main: [ { - set: { - setIdentifier: 'NASAL_PULMONIC_CONSONANTS', - setExpression: [ 'm̥', 'm', 'ɱ' ] - } + type: 'set', + setIdentifier: 'NASAL_PULMONIC_CONSONANTS', + setExpression: [ 'm̥', 'm', 'ɱ' ] } ] } @@ -161,17 +160,15 @@ set NASAL_PULMONIC_CONSONANTS = [ m̥, m, ɱ, n̼, n̥, n, ɳ̊, ], AST: { main: [ - { - set: [ - { - setIdentifier: 'NASAL_PULMONIC_CONSONANTS', - items: [ 'm̥', 'm', 'ɱ', 'n̼', 'n̥', 'n', 'ɳ̊', 'ɳ', 'ɲ̊', 'ɲ', `ŋ`, ' ̊ŋ', 'ɴ' ] - }, - { - setIdentifier: 'STOP_PULMONIC_CONSONANTS', - items: [ 'p', 'b', 'p̪', 'b̪', 't̼', 'd̼', 't', 'd', 'ʈ', 'ɖ', 'c', 'ɟ', 'k', 'ɡ', 'q', 'ɢ', 'ʡ', 'ʔ' ] - } - ] + { + type: 'set', + setIdentifier: 'NASAL_PULMONIC_CONSONANTS', + setExpression: [ 'm̥', 'm', 'ɱ', 'n̼', 'n̥', 'n', 'ɳ̊', 'ɳ', 'ɲ̊', 'ɲ', 'ŋ', '̊ŋ', 'ɴ' ] + }, + { + type: 'set', + setIdentifier: 'STOP_PULMONIC_CONSONANTS', + setExpression: [ 'p', 'b', 'p̪', 'b̪', 't̼', 'd̼', 't', 'd', 'ʈ', 'ɖ', 'c', 'ɟ', 'k', 'ɡ', 'q', 'ɢ', 'ʡ', 'ʔ' ] } ] }