patch issues with phone token context
This commit is contained in:
parent
5c2138e04f
commit
20bede405f
3 changed files with 101 additions and 30 deletions
|
@ -110,7 +110,7 @@ const parseReferent = (tree, token, index, tokens) => {
|
||||||
}
|
}
|
||||||
case 'epoch-name': {
|
case 'epoch-name': {
|
||||||
tree[tree.length - 1] = {...lastNode, name: token.value, type: 'epoch' }
|
tree[tree.length - 1] = {...lastNode, name: token.value, type: 'epoch' }
|
||||||
return tree;
|
return [...tree, { type: 'main'}];
|
||||||
}
|
}
|
||||||
case 'epoch': {
|
case 'epoch': {
|
||||||
return [...tree, { type: 'rule', value: token.value } ]
|
return [...tree, { type: 'rule', value: token.value } ]
|
||||||
|
@ -148,6 +148,15 @@ const parseReferent = (tree, token, index, tokens) => {
|
||||||
tree[tree.length - 1] = lastNode;
|
tree[tree.length - 1] = lastNode;
|
||||||
return [...tree]
|
return [...tree]
|
||||||
}
|
}
|
||||||
|
case 'lexicon': {
|
||||||
|
if (!lastNode.epoch) {
|
||||||
|
tree[tree.length - 1].epoch = token.value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tree[tree.length - 1].value.push(token.value)
|
||||||
|
}
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return [...tree, `unexpected referent ${token.value}`]
|
return [...tree, `unexpected referent ${token.value}`]
|
||||||
}
|
}
|
||||||
|
@ -160,6 +169,14 @@ const parsePhone = (tree, token, index, tokens) => {
|
||||||
tree[tree.length - 1] = {...lastNode, value: lastNode.value + token.value }
|
tree[tree.length - 1] = {...lastNode, value: lastNode.value + token.value }
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
case 'feature--plus':
|
||||||
|
lastNode.positivePhones = [...lastNode.positivePhones, token.value ];
|
||||||
|
tree[tree.length - 1] = lastNode;
|
||||||
|
return tree;
|
||||||
|
case 'feature--minus':
|
||||||
|
lastNode.negativePhones = [...lastNode.negativePhones, token.value ];
|
||||||
|
tree[tree.length - 1] = lastNode;
|
||||||
|
return tree;
|
||||||
default:
|
default:
|
||||||
return [...tree, `unexpected phone ${token.value}`]
|
return [...tree, `unexpected phone ${token.value}`]
|
||||||
}
|
}
|
||||||
|
@ -182,6 +199,8 @@ const parseOpenBracket = (tree, token, index, tokens) => {
|
||||||
return [...tree, {type: 'feature', positivePhones: [], negativePhones: []}];
|
return [...tree, {type: 'feature', positivePhones: [], negativePhones: []}];
|
||||||
case 'feature--minus':
|
case 'feature--minus':
|
||||||
return [...tree, {type: 'feature', positivePhones: [], negativePhones: []}];
|
return [...tree, {type: 'feature', positivePhones: [], negativePhones: []}];
|
||||||
|
case 'main':
|
||||||
|
return [...tree, {type: 'feature', positivePhones: [], negativePhones: []}];
|
||||||
default:
|
default:
|
||||||
return [...tree, 'unexpected open bracket']
|
return [...tree, 'unexpected open bracket']
|
||||||
}
|
}
|
||||||
|
@ -285,6 +304,7 @@ const parseGreaterThan = (tree, token, index, tokens) => {
|
||||||
|
|
||||||
const parseSlash = (tree, token, index, tokens) => {
|
const parseSlash = (tree, token, index, tokens) => {
|
||||||
const lastNode = tree[tree.length - 1];
|
const lastNode = tree[tree.length - 1];
|
||||||
|
if (lastNode) {
|
||||||
switch (lastNode.type) {
|
switch (lastNode.type) {
|
||||||
case 'rule':
|
case 'rule':
|
||||||
tree[tree.length - 1] = {...lastNode, value: lastNode.value + token.value}
|
tree[tree.length - 1] = {...lastNode, value: lastNode.value + token.value}
|
||||||
|
@ -293,9 +313,13 @@ const parseSlash = (tree, token, index, tokens) => {
|
||||||
return tree;
|
return tree;
|
||||||
case 'feature--minus':
|
case 'feature--minus':
|
||||||
return tree;
|
return tree;
|
||||||
|
case 'lexicon':
|
||||||
|
return [...tree, { }]
|
||||||
default:
|
default:
|
||||||
return [...tree, 'unexpected slash']
|
return [...tree, 'unexpected slash']
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return [...tree, { type: 'lexicon', value: []}]
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseHash = (tree, token, index, tokens) => {
|
const parseHash = (tree, token, index, tokens) => {
|
||||||
|
@ -381,6 +405,7 @@ const generateNode = (tree, token, index, tokens) => {
|
||||||
const addToken = (tree, token, index, tokens) => generateNode(tree, token, index, tokens);
|
const addToken = (tree, token, index, tokens) => generateNode(tree, token, index, tokens);
|
||||||
|
|
||||||
const connectNodes = (tree, node, index, nodes) => {
|
const connectNodes = (tree, node, index, nodes) => {
|
||||||
|
console.log(tree, node)
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case 'epoch':
|
case 'epoch':
|
||||||
delete node.type;
|
delete node.type;
|
||||||
|
@ -408,6 +433,9 @@ const connectNodes = (tree, node, index, nodes) => {
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
return {...tree, features: [...tree.features, {...node} ] }
|
return {...tree, features: [...tree.features, {...node} ] }
|
||||||
|
case 'lexicon':
|
||||||
|
delete node.type;
|
||||||
|
return {...tree, lexicon: [...tree.lexicon, node]}
|
||||||
default:
|
default:
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
@ -417,7 +445,7 @@ export const buildTree = tokens => {
|
||||||
const bareTree = {
|
const bareTree = {
|
||||||
epochs: [],
|
epochs: [],
|
||||||
features: [],
|
features: [],
|
||||||
phones: []
|
lexicon: []
|
||||||
}
|
}
|
||||||
const nodes = tokens.reduce(addToken, []);
|
const nodes = tokens.reduce(addToken, []);
|
||||||
// return nodes
|
// return nodes
|
||||||
|
@ -434,8 +462,8 @@ export const generateAST = latl => {
|
||||||
// tokenize
|
// tokenize
|
||||||
const tokens = tokenize(latl.trim());
|
const tokens = tokenize(latl.trim());
|
||||||
// build tree
|
// build tree
|
||||||
console.log(tokens)
|
|
||||||
const tree = buildTree(tokens);
|
const tree = buildTree(tokens);
|
||||||
|
console.log(tree)
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +472,7 @@ export const parseLatl = (state, action) => {
|
||||||
const latl = state.latl;
|
const latl = state.latl;
|
||||||
const AST = generateAST(latl);
|
const AST = generateAST(latl);
|
||||||
const features = AST.features;
|
const features = AST.features;
|
||||||
|
console.log(AST)
|
||||||
if (features) {
|
if (features) {
|
||||||
if (state.features) {
|
if (state.features) {
|
||||||
state = Object.keys(state.features).reduce((state, feature) => {
|
state = Object.keys(state.features).reduce((state, feature) => {
|
||||||
|
@ -453,12 +482,23 @@ export const parseLatl = (state, action) => {
|
||||||
state = features.reduce((state, feature) => stateReducer(state, {type:'ADD_FEATURE', value: feature}), state);
|
state = features.reduce((state, feature) => stateReducer(state, {type:'ADD_FEATURE', value: feature}), state);
|
||||||
}
|
}
|
||||||
delete AST.features;
|
delete AST.features;
|
||||||
|
const lexicon = AST.lexicon;
|
||||||
|
if (lexicon) {
|
||||||
|
if (state.lexicon) {
|
||||||
|
state.lexicon = [];
|
||||||
|
}
|
||||||
|
state = lexicon.reduce((state, epoch) => {
|
||||||
|
return epoch.value.reduce((reducedState, lexeme) => {
|
||||||
|
return stateReducer(reducedState, {type: 'ADD_LEXEME', value: { lexeme, epoch: epoch.epoch }})
|
||||||
|
}, state)
|
||||||
|
}, state)
|
||||||
|
}
|
||||||
|
delete AST.lexicon;
|
||||||
Object.entries(AST).forEach(([key, value]) => state[key] = value);
|
Object.entries(AST).forEach(([key, value]) => state[key] = value);
|
||||||
return { ...state, parseResults: 'latl parsed successfully', results:[] }
|
return { ...state, parseResults: 'latl parsed successfully', results:[] }
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
console.log(e)
|
return { ...state, parseResults: 'error parsing', errors: e}
|
||||||
return { ...state, parseResults: e}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,18 +23,18 @@ describe('LATL', () => {
|
||||||
expect(tokens).toStrictEqual(tokenizedFeature);
|
expect(tokens).toStrictEqual(tokenizedFeature);
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('returns tokens from well-formed latl lexicon definition', () => {
|
it('returns tokens from well-formed latl lexicon definition', () => {
|
||||||
// const tokens = tokenize(lexiconDefinitionLatl);
|
const tokens = tokenize(lexiconDefinitionLatl);
|
||||||
// expect(tokens).toStrictEqual(tokenizedLexicon);
|
expect(tokens).toStrictEqual(tokenizedLexicon);
|
||||||
// });
|
});
|
||||||
|
|
||||||
// it('returns tokens from well-formed latl epoch, feature, and lexicon definitions', () => {
|
it('returns tokens from well-formed latl epoch, feature, and lexicon definitions', () => {
|
||||||
// const latl = epochDefinitionLatl + '\n' + featureDefinitionLatl + '\n' + lexiconDefinitionLatl;
|
const latl = epochDefinitionLatl + '\n' + featureDefinitionLatl + '\n' + lexiconDefinitionLatl;
|
||||||
// const tokens = tokenize(latl);
|
const tokens = tokenize(latl);
|
||||||
// const lineBreaks = [{ type: 'lineBreak', value: '' },{ type: 'lineBreak', value: '' },{ type: 'lineBreak', value: '' }]
|
const lineBreaks = [{ type: 'lineBreak', value: '' },{ type: 'lineBreak', value: '' },{ type: 'lineBreak', value: '' }]
|
||||||
// const tokenizedLatl = [...tokenizedEpoch, ...lineBreaks, ...tokenizedFeature, ...lineBreaks, ...tokenizedLexicon];
|
const tokenizedLatl = [...tokenizedEpoch, ...lineBreaks, ...tokenizedFeature, ...lineBreaks, ...tokenizedLexicon];
|
||||||
// expect(tokens).toStrictEqual(tokenizedLatl);
|
expect(tokens).toStrictEqual(tokenizedLatl);
|
||||||
// });
|
});
|
||||||
|
|
||||||
it('returns AST from well-formed epoch tokens', () => {
|
it('returns AST from well-formed epoch tokens', () => {
|
||||||
const tree = buildTree(tokenizedEpoch);
|
const tree = buildTree(tokenizedEpoch);
|
||||||
|
@ -46,6 +46,11 @@ describe('LATL', () => {
|
||||||
expect(tree).toStrictEqual(treeFeature);
|
expect(tree).toStrictEqual(treeFeature);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('returns AST from well-formed lexicon tokens', () => {
|
||||||
|
const tree = buildTree(tokenizedLexicon);
|
||||||
|
expect(tree).toStrictEqual(treeLexicon);
|
||||||
|
})
|
||||||
|
|
||||||
it('parse returns state from well-formed feature latl', () => {
|
it('parse returns state from well-formed feature latl', () => {
|
||||||
const state = initState();
|
const state = initState();
|
||||||
const setAction = {
|
const setAction = {
|
||||||
|
@ -71,6 +76,18 @@ describe('LATL', () => {
|
||||||
expect(runState).toStrictEqual({...runState, results: runEpochResults})
|
expect(runState).toStrictEqual({...runState, results: runEpochResults})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('returns state from well-formed lexicon latl', () => {
|
||||||
|
const state = initState();
|
||||||
|
const setAction = {
|
||||||
|
type: 'SET_LATL',
|
||||||
|
value: lexiconDefinitionLatl
|
||||||
|
}
|
||||||
|
const latlState = stateReducer(state, setAction);
|
||||||
|
const parseState = parseLatl(latlState, {});
|
||||||
|
expect(parseState).toStrictEqual(lexiconState)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
const epochDefinitionLatl = `
|
const epochDefinitionLatl = `
|
||||||
; comment
|
; comment
|
||||||
|
@ -462,7 +479,19 @@ const lexiconDefinitionLatl = `
|
||||||
|
|
||||||
const tokenizedLexicon = [
|
const tokenizedLexicon = [
|
||||||
{ type: "slash", value: "/" }, { type: "referent", value: "PROTO" }, { type: 'lineBreak', value: '' },
|
{ type: "slash", value: "/" }, { type: "referent", value: "PROTO" }, { type: 'lineBreak', value: '' },
|
||||||
{ type: "referent", value: "kpn" }, { type: 'lineBreak', value: '' },
|
{ type: "whiteSpace", value:"" }, { type: "referent", value: "kpn" }, { type: 'lineBreak', value: '' },
|
||||||
{ type: "referent", value: "sm" }, { type: 'lineBreak', value: '' },
|
{ type: "whiteSpace", value:"" }, { type: "referent", value: "sm" }, { type: 'lineBreak', value: '' },
|
||||||
{ type: "slash", value: "/" }
|
{ type: "slash", value: "/" }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const treeLexicon = {lexicon: [{epoch: "PROTO", value: ["kpn", "sm"]}]};
|
||||||
|
|
||||||
|
const lexiconState = {
|
||||||
|
...initState(),
|
||||||
|
latl: lexiconDefinitionLatl,
|
||||||
|
lexicon: [
|
||||||
|
{ lexeme: 'kpn', epoch: 'PROTO'},
|
||||||
|
{ lexeme: 'sm', epoch: 'PROTO'}
|
||||||
|
],
|
||||||
|
parseResults: 'latl parsed successfully'
|
||||||
|
}
|
|
@ -20,8 +20,10 @@ const makeLexeme = (lexeme: string, epochName: ?string, state: stateType) => {
|
||||||
const newLexeme = {lexeme: lexeme, epoch: state.epochs[0]};
|
const newLexeme = {lexeme: lexeme, epoch: state.epochs[0]};
|
||||||
if (epochName) {
|
if (epochName) {
|
||||||
const epochIndex = state.epochs.findIndex(epoch => epoch.name === epochName);
|
const epochIndex = state.epochs.findIndex(epoch => epoch.name === epochName);
|
||||||
if (epochIndex > 0) {
|
if (epochIndex > -1) {
|
||||||
newLexeme.epoch = state.epochs[epochIndex];
|
newLexeme.epoch = state.epochs[epochIndex];
|
||||||
|
} else {
|
||||||
|
newLexeme.epoch = epochName;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return newLexeme;
|
return newLexeme;
|
||||||
|
|
Loading…
Reference in a new issue