From d25bd325b7f6f72208b6775ab85473e72ede5432 Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Fri, 3 Jan 2025 06:32:55 +0100 Subject: [PATCH] symbol-map.go: improved detection of incomplete operations --- symbol-map.go | 184 ++++++++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 88 deletions(-) diff --git a/symbol-map.go b/symbol-map.go index 0f321f7..2ab988e 100644 --- a/symbol-map.go +++ b/symbol-map.go @@ -14,7 +14,7 @@ type symbolClass int16 const ( symClassOperator symbolClass = iota - symClassPostOp + symClassCommand symClassIdentifier symClassDelimiter symClassParenthesis @@ -24,83 +24,84 @@ const ( ) type symbolSpec struct { - repr string - kind symbolClass + repr string + kind symbolClass + opType termPosition } func init() { symbolMap = map[Symbol]symbolSpec{ - SymUnknown: {"", symClassOther}, // -1: Unknown symbol - SymNone: {"", symClassOther}, // 0: Null value for variable of type symbol - SymError: {"", symClassOther}, // 1: Error reading from stream - SymEos: {"", symClassOther}, // 2: End of stream - SymMinus: {"-", symClassOperator}, // 3: '-' - SymMinusEqual: {"-=", symClassOperator}, // 4: '-=' - SymDoubleMinus: {"--", symClassOperator}, // 5: '--' - SymPlus: {"+", symClassOperator}, // 6: '+' - SymPlusEqual: {"+=", symClassOperator}, // 7: '+=' - SymDoublePlus: {"++", symClassOperator}, // 8: '++' - SymStar: {"*", symClassOperator}, // 9: '*' - SymDoubleStar: {"**", symClassOperator}, // 10: '**' - SymSlash: {"/", symClassOperator}, // 11: '/' - SymBackSlash: {"\\", symClassOperator}, // 12: '\' - SymVertBar: {"|", symClassOperator}, // 13: '|' - SymDoubleVertBar: {"||", symClassOperator}, // 14: '||' - SymComma: {",", symClassOperator}, // 15: ',' - SymColon: {":", symClassOperator}, // 16: ':' - SymSemiColon: {";", symClassOperator}, // 17: ';' - SymDot: {".", symClassOperator}, // 18: '.' - SymDotSlash: {"./", symClassOperator}, // 19: './' - SymQuote: {"'", symClassDelimiter}, // 20: '\'' - SymDoubleQuote: {"\"", symClassDelimiter}, // 21: '"' - SymBackTick: {"`", symClassOperator}, // 22: '`' - SymExclamation: {"!", symClassPostOp}, // 23: '!' - SymQuestion: {"?", symClassOperator}, // 24: '?' - SymAmpersand: {"&", symClassOperator}, // 25: '&' - SymDoubleAmpersand: {"&&", symClassOperator}, // 26: '&&' - SymPercent: {"%", symClassOperator}, // 27: '%' - SymAt: {"@", symClassOperator}, // 28: '@' - SymUndescore: {"_", symClassOperator}, // 29: '_' - SymEqual: {"=", symClassOperator}, // 30: '=' - SymDoubleEqual: {"==", symClassOperator}, // 31: '==' - SymLess: {"<", symClassOperator}, // 32: '<' - SymLessOrEqual: {"<=", symClassOperator}, // 33: '<=' - SymGreater: {">", symClassOperator}, // 34: '>' - SymGreaterOrEqual: {">=", symClassOperator}, // 35: '>=' - SymLessGreater: {"<>", symClassOperator}, // 36: '<>' - SymNotEqual: {"!=", symClassOperator}, // 37: '!=' - SymDollar: {"$", symClassOperator}, // 38: '$' - SymHash: {"#", symClassOperator}, // 39: '#' - SymOpenRound: {"(", symClassParenthesis}, // 40: '(' - SymClosedRound: {")", symClassParenthesis}, // 41: ')' - SymOpenSquare: {"[", symClassParenthesis}, // 42: '[' - SymClosedSquare: {"]", symClassParenthesis}, // 43: ']' - SymOpenBrace: {"{", symClassParenthesis}, // 44: '{' - SymClosedBrace: {"}", symClassParenthesis}, // 45: '}' - SymTilde: {"~", symClassOperator}, // 46: '~' - SymDoubleQuestion: {"??", symClassOperator}, // 47: '??' - SymQuestionEqual: {"?=", symClassOperator}, // 48: '?=' - SymQuestionExclam: {"?!", symClassOperator}, // 49: '?!' - SymDoubleAt: {"@@", symClassOperator}, // 50: '@@' - SymDoubleColon: {"::", symClassOperator}, // 51: '::' - SymDoubleGreater: {">>", symClassOperator}, // 52: '>>' - SymDoubleLess: {"<<", symClassOperator}, // 53: '<<' - SymCaret: {"^", symClassOperator}, // 54: '^' - SymDollarRound: {"$(", symClassOperator}, // 55: '$(' - SymOpenClosedRound: {"()", symClassPostOp}, // 56: '()' - SymDoubleDollar: {"$$", symClassOperator}, // 57: '$$' - SymDoubleDot: {"..", symClassOperator}, // 58: '..' - SymTripleDot: {"...", symClassOperator}, // 59: '...' - SymStarEqual: {"*=", symClassOperator}, // 60: '*=' - SymSlashEqual: {"/=", symClassOperator}, // 61: '/=' - SymPercEqual: {"%=", symClassOperator}, // 62: '%=' - SymDoubleLessEqual: {"<<=", symClassOperator}, // 63: '<<=' - SymDoubleGreaterEqual: {">>=", symClassOperator}, // 64: '>>=' - SymAmpersandEqual: {"&=", symClassOperator}, // 65: '&=' - SymVertBarEqual: {"|=", symClassOperator}, // 65: '|=' - SymPlusGreater: {"+>", symClassOperator}, // 66: '+>' - SymLessPlus: {"<+", symClassOperator}, // 67: '<+' + SymUnknown: {"", symClassOther, posLeaf}, // -1: Unknown symbol + SymNone: {"", symClassOther, posLeaf}, // 0: Null value for variable of type symbol + SymError: {"", symClassOther, posLeaf}, // 1: Error reading from stream + SymEos: {"", symClassOther, posLeaf}, // 2: End of stream + SymMinus: {"-", symClassOperator, posInfix}, // 3: '-' + SymMinusEqual: {"-=", symClassOperator, posInfix}, // 4: '-=' + SymDoubleMinus: {"--", symClassOperator, posPostfix}, // 5: '--' + SymPlus: {"+", symClassOperator, posInfix}, // 6: '+' + SymPlusEqual: {"+=", symClassOperator, posInfix}, // 7: '+=' + SymDoublePlus: {"++", symClassOperator, posPostfix}, // 8: '++' + SymStar: {"*", symClassOperator, posInfix}, // 9: '*' + SymDoubleStar: {"**", symClassOperator, posInfix}, // 10: '**' + SymSlash: {"/", symClassOperator, posInfix}, // 11: '/' + SymBackSlash: {"\\", symClassOperator, posLeaf}, // 12: '\' + SymVertBar: {"|", symClassOperator, posInfix}, // 13: '|' + SymDoubleVertBar: {"||", symClassOperator, posInfix}, // 14: '||' + SymComma: {",", symClassOperator, posInfix}, // 15: ',' + SymColon: {":", symClassOperator, posInfix}, // 16: ':' + SymSemiColon: {";", symClassOperator, posInfix}, // 17: ';' + SymDot: {".", symClassOperator, posInfix}, // 18: '.' + SymDotSlash: {"./", symClassOperator, posInfix}, // 19: './' + SymQuote: {"'", symClassDelimiter, posLeaf}, // 20: '\'' + SymDoubleQuote: {"\"", symClassDelimiter, posLeaf}, // 21: '"' + SymBackTick: {"`", symClassDelimiter, posLeaf}, // 22: '`' + SymExclamation: {"!", symClassOperator, posPostfix}, // 23: '!' + SymQuestion: {"?", symClassOperator, posInfix}, // 24: '?' + SymAmpersand: {"&", symClassOperator, posInfix}, // 25: '&' + SymDoubleAmpersand: {"&&", symClassOperator, posInfix}, // 26: '&&' + SymPercent: {"%", symClassOperator, posInfix}, // 27: '%' + SymAt: {"@", symClassOperator, posPrefix}, // 28: '@' + SymUndescore: {"_", symClassIdentifier, posLeaf}, // 29: '_' + SymEqual: {"=", symClassOperator, posInfix}, // 30: '=' + SymDoubleEqual: {"==", symClassOperator, posInfix}, // 31: '==' + SymLess: {"<", symClassOperator, posInfix}, // 32: '<' + SymLessOrEqual: {"<=", symClassOperator, posInfix}, // 33: '<=' + SymGreater: {">", symClassOperator, posInfix}, // 34: '>' + SymGreaterOrEqual: {">=", symClassOperator, posInfix}, // 35: '>=' + SymLessGreater: {"<>", symClassOperator, posInfix}, // 36: '<>' + SymNotEqual: {"!=", symClassOperator, posInfix}, // 37: '!=' + SymDollar: {"$", symClassOperator, posPrefix}, // 38: '$' + SymHash: {"#", symClassOperator, posPrefix}, // 39: '#' + SymOpenRound: {"(", symClassParenthesis, posPrefix}, // 40: '(' + SymClosedRound: {")", symClassParenthesis, posPostfix}, // 41: ')' + SymOpenSquare: {"[", symClassParenthesis, posPrefix}, // 42: '[' + SymClosedSquare: {"]", symClassParenthesis, posPostfix}, // 43: ']' + SymOpenBrace: {"{", symClassParenthesis, posPrefix}, // 44: '{' + SymClosedBrace: {"}", symClassParenthesis, posPostfix}, // 45: '}' + SymTilde: {"~", symClassOperator, posPrefix}, // 46: '~' + SymDoubleQuestion: {"??", symClassOperator, posInfix}, // 47: '??' + SymQuestionEqual: {"?=", symClassOperator, posInfix}, // 48: '?=' + SymQuestionExclam: {"?!", symClassOperator, posInfix}, // 49: '?!' + SymDoubleAt: {"@@", symClassCommand, posLeaf}, // 50: '@@' + SymDoubleColon: {"::", symClassOperator, posInfix}, // 51: '::' + SymDoubleGreater: {">>", symClassOperator, posInfix}, // 52: '>>' + SymDoubleLess: {"<<", symClassOperator, posInfix}, // 53: '<<' + SymCaret: {"^", symClassOperator, posInfix}, // 54: '^' + SymDollarRound: {"$(", symClassOperator, posPrefix}, // 55: '$(' + SymOpenClosedRound: {"()", symClassOperator, posPostfix}, // 56: '()' + SymDoubleDollar: {"$$", symClassCommand, posLeaf}, // 57: '$$' + SymDoubleDot: {"..", symClassOperator, posInfix}, // 58: '..' + SymTripleDot: {"...", symClassOperator, posPostfix}, // 59: '...' + SymStarEqual: {"*=", symClassOperator, posInfix}, // 60: '*=' + SymSlashEqual: {"/=", symClassOperator, posInfix}, // 61: '/=' + SymPercEqual: {"%=", symClassOperator, posInfix}, // 62: '%=' + SymDoubleLessEqual: {"<<=", symClassOperator, posInfix}, // 63: '<<=' + SymDoubleGreaterEqual: {">>=", symClassOperator, posInfix}, // 64: '>>=' + SymAmpersandEqual: {"&=", symClassOperator, posInfix}, // 65: '&=' + SymVertBarEqual: {"|=", symClassOperator, posInfix}, // 65: '|=' + SymPlusGreater: {"+>", symClassOperator, posInfix}, // 66: '+>' + SymLessPlus: {"<+", symClassOperator, posInfix}, // 67: '<+' // SymChangeSign // SymUnchangeSign // SymIdentifier @@ -127,17 +128,17 @@ func init() { // // SymClosedComment // 0: '*/' // // SymOneLineComment // 0: '//' // keywordBase - SymKwAnd: {"and", symClassOperator}, - SymKwNot: {"not", symClassOperator}, - SymKwOr: {"or", symClassOperator}, - SymKwBut: {"but", symClassOperator}, - SymKwFunc: {"func(", symClassDeclaration}, - SymKwBuiltin: {"builtin", symClassOperator}, - SymKwPlugin: {"plugin", symClassOperator}, - SymKwIn: {"in", symClassOperator}, - SymKwInclude: {"include", symClassOperator}, - SymKwNil: {"nil", symClassValue}, - SymKwUnset: {"unset", symClassOperator}, + SymKwAnd: {"and", symClassOperator, posInfix}, + SymKwNot: {"not", symClassOperator, posInfix}, + SymKwOr: {"or", symClassOperator, posInfix}, + SymKwBut: {"but", symClassOperator, posInfix}, + SymKwFunc: {"func(", symClassDeclaration, posPrefix}, + SymKwBuiltin: {"builtin", symClassOperator, posPrefix}, + SymKwPlugin: {"plugin", symClassOperator, posPrefix}, + SymKwIn: {"in", symClassOperator, posInfix}, + SymKwInclude: {"include", symClassOperator, posPrefix}, + SymKwNil: {"nil", symClassValue, posLeaf}, + SymKwUnset: {"unset", symClassOperator, posPrefix}, } } @@ -175,12 +176,19 @@ func StringEndsWithOperator(s string) bool { } func endingOperator(s string) (sym Symbol) { + var matchLength = 0 sym = SymNone - lower := strings.ToLower(s) + lower := strings.TrimRight(strings.ToLower(s), " \t") for symbol, spec := range symbolMap { - if spec.kind == symClassOperator && strings.HasSuffix(lower, spec.repr) { - sym = symbol - break + if strings.HasSuffix(lower, spec.repr) { + if len(spec.repr) > matchLength { + matchLength = len(spec.repr) + if spec.kind == symClassOperator && (spec.opType == posInfix || spec.opType == posPrefix) { + sym = symbol + } else { + sym = SymNone + } + } } } return