add error check for unknown tokens in feature portions of rules
This commit is contained in:
parent
54dbe75a70
commit
6885aeba2f
2 changed files with 71 additions and 35 deletions
|
@ -89,20 +89,39 @@ const decomposeRule = (rule: string, index: number): ruleBundle => {
|
|||
}
|
||||
}
|
||||
|
||||
const doesFeatureRuleContainUnknownToken = features => {
|
||||
const unknownTokens = features
|
||||
.match(/\W/g)
|
||||
.filter(v => v !== '-' && v !== '+' && v !== ']' && v !== '[' && v !== ' ')
|
||||
if (unknownTokens.length) throw `Unknown token '${unknownTokens[0]}'`;
|
||||
return true
|
||||
}
|
||||
|
||||
const getPositiveFeatures = phoneme => {
|
||||
try {
|
||||
const positiveFeatures = phoneme.match(/(?=\+.).*(?<=\-)|(?=\+.).*(?!\-).*(?<=\])/g)
|
||||
if (positiveFeatures) doesFeatureRuleContainUnknownToken(positiveFeatures[0])
|
||||
return positiveFeatures ? positiveFeatures[0]
|
||||
.trim().match(/\w+/g)
|
||||
.reduce((map, feature) => ({...map, [feature]: true}), {})
|
||||
: {}
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const getNegativeFeatures = phoneme => {
|
||||
try {
|
||||
const negativeFeatures = phoneme.match(/(?=\-.).*(?<=\+)|(?=\-.).*(?!\+).*(?<=\])/g)
|
||||
if (negativeFeatures) doesFeatureRuleContainUnknownToken(negativeFeatures[0])
|
||||
return negativeFeatures ? negativeFeatures[0]
|
||||
.trim().match(/\w+/g)
|
||||
.trim()
|
||||
.match(/\w+/g)
|
||||
.reduce((map, feature) => ({...map, [feature]: false}), {})
|
||||
: {}
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const mapToPositiveAndNegativeFeatures = phoneme => (
|
||||
|
@ -114,6 +133,7 @@ const mapStringToFeatures = (ruleString, phones) => {
|
|||
if (ruleString === '#') return ['#']
|
||||
if (ruleString === '0') return [];
|
||||
const ruleBrackets = ruleString.match(/\[.*\]/)
|
||||
try {
|
||||
if (ruleBrackets) {
|
||||
return ruleString
|
||||
.split('[')
|
||||
|
@ -122,12 +142,16 @@ const mapStringToFeatures = (ruleString, phones) => {
|
|||
.map(mapToPositiveAndNegativeFeatures)
|
||||
}
|
||||
return findFeaturesFromGrapheme(phones, ruleString);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
const mapRuleBundleToFeatureBundle = phones => ruleBundle => {
|
||||
const mapRuleBundleToFeatureBundle = phones => ( ruleBundle, index ) => {
|
||||
// for each object in ruleBundle, map values to array of objects with feature-boolean key-value pairs
|
||||
try {
|
||||
const { newFeatures, environment:{ pre, position, post } } = ruleBundle;
|
||||
return {
|
||||
environment: {
|
||||
|
@ -137,6 +161,9 @@ const mapRuleBundleToFeatureBundle = phones => ruleBundle => {
|
|||
},
|
||||
newFeatures: mapStringToFeatures(newFeatures, phones)
|
||||
}
|
||||
} catch (err) {
|
||||
throw errorMessage`Error in line ${index + 1}: ${err}`;
|
||||
}
|
||||
}
|
||||
|
||||
export const decomposeRules = (epoch: epochType, phones: {[key: string]: phoneType}): decomposedRulesType => {
|
||||
|
@ -228,8 +255,8 @@ const stringifyResults = lexemeBundle => Object.entries(lexemeBundle).map(getGra
|
|||
export const run = (state: stateType, action: resultsAction): stateType => {
|
||||
|
||||
// TODO iterate through each epoch
|
||||
try {
|
||||
const epoch = state.epochs[0];
|
||||
|
||||
const { phones, lexicon, features } = state;
|
||||
|
||||
const ruleBundle = decomposeRules(epoch, phones);
|
||||
|
@ -242,4 +269,7 @@ export const run = (state: stateType, action: resultsAction): stateType => {
|
|||
}
|
||||
|
||||
return {...state, results: [pass] }
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
|
@ -55,6 +55,12 @@ describe('Results', () => {
|
|||
expect(decomposeRules(epoch, phones)).toEqual("Error in line 1: Too many '_' operators");
|
||||
})
|
||||
|
||||
it('rule with incorrect feature syntax returns helpful error message', () => {
|
||||
const { phones } = initState();
|
||||
const epoch = { name: 'error epoch', changes: [ '[+ occlusive - nasal = obstruent]>n/_' ] }
|
||||
expect(decomposeRules(epoch, phones)).toEqual("Error in line 1: Unknown token '='");
|
||||
})
|
||||
|
||||
it('expect transform lexeme to apply rule to lexeme', () => {
|
||||
const lexemeBundle = getlexemeBundle();
|
||||
const resultsLexeme = [...lexemeBundle]
|
||||
|
|
Loading…
Reference in a new issue