也许这个问题有点奇怪,但我真的想得到一些关于这个问题的观点。
我用JavaScript开发了一个Web项目。它具有模块化架构(除某些特定情况外,大多数代码都 Package 在类中),其中一个模块称为tokenizer
。另外,我有一个名为utils
的目录,其中包含一个包含tokenizer
模块的util函数的文件。
这个文件看起来像这样:
import SymbolStringRepresentation from '@utils/enums/symbol';
import TokenType from '@utils/enums/tokenType';
import OperatorType from '@utils/enums/operatorType';
import AssociativityType from '@utils/enums/associativityType';
import * as regexp from '@utils/regexp';
import {UnknownTokenTypeError} from '@error/customErrors';
/**
* Checks whether provided token is a left parenthesis.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the token is a left parenthesis.
* False otherwise.
*/
function isLeftParenthesis(token) {
return token.getValue() === SymbolStringRepresentation.LEFT_PARENTHESIS;
}
/**
* Checks whether provided token is a right parenthesis.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the token is a right parenthesis.
* False otherwise.
*/
function isRightParenthesis(token) {
return token.getValue() === SymbolStringRepresentation.RIGHT_PARENTHESIS;
}
/**
* Checks whether the provided token is an operator.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the provided token is an operator.
* False otherwise.
*/
function isOperator(token) {
return token.getType() === TokenType.OPERATOR;
}
/**
* Checks whether the provided token is a unary operator.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the provided token is a unary operator.
* False otherwise.
*/
function isUnaryOperator(token) {
return token.getValue().type === OperatorType.UNARY;
}
/**
* Checks whether the provided token is a binary operator.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the provided token is a binary operator.
* False otherwise.
*/
function isBinaryOperator(token) {
return token.getValue().type === OperatorType.BINARY;
}
/**
* Checks whether the provided token is right-associative.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the provided token is right-associative.
* False otherwise.
*/
function isRightAssociative(token) {
return token.getValue().associativity === AssociativityType.RIGHT;
}
/**
* Checks whether the provided token is a literal.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the provided token is a literal.
* False otherwise.
*/
function isLiteral(token) {
return token.getType() === TokenType.LITERAL;
}
/**
* Checks whether the provided token is a literal or
* an operator with right associativity.
*
* @param {Token} token Token to check.
* @returns {boolean} True if the provided token is a literal or
* an operator with right associativity.
*/
function isLiteralOrOperatorWithRightAssociativity(token) {
return (
isLiteral(token) ||
(isOperator(token) && isRightAssociative(token))
);
}
/**
* Determines the token type of provided mathematical expression member.
*
* @param {string} expressionMember The expression member to determine the type of.
* @returns {string} The token type of the expression member.
* @throws {UnknownTokenTypeError} If the type of the expression member is unknown.
*/
function getTokenTypeOf(expressionMember) {
const matchesRegexp = createTestRegexpFunction(expressionMember);
if (matchesRegexp(regexp.digits)) {
return TokenType.LITERAL;
} else if (matchesRegexp(regexp.parenthesis)) {
return TokenType.PARENTHESIS;
} else if (matchesRegexp(regexp.operator) || matchesRegexp(regexp.letters)) {
return TokenType.OPERATOR;
}
throw new UnknownTokenTypeError(`Unknown token type of the member: ${expressionMember}`);
}
/**
* Determines whether provided expression members are of
* the same token type.
*
* @param {string} member1 First expression member.
* @param {string} member2 Second expression member.
* @returns {boolean} True if the expression members have the same
* token type. False otherwise.
*/
function isSameTokenType(member1, member2) {
return getTokenTypeOf(member1) === getTokenTypeOf(member2);
}
/**
* Checks whether the provided type is literal or parenthesis.
*
* @param {string} type Token type to check.
* @returns {boolean} True is the provided token type is a literal
* or parenthesis. False otherwise.
*/
function isTypeOfLiteralOrParenthesis(type) {
return (
type === TokenType.LITERAL
|| type === TokenType.PARENTHESIS
);
}
/**
* Checks whether the provided type is function or operator.
*
* @param {string} type Token type to check.
* @returns {boolean} True is the provided token type is a function
* or an operator. False otherwise.
*/
function isOfTypeOperator(type) {
return type === TokenType.OPERATOR;
}
/**
* Helper higher-order method for creating a function for regexp testing.
*
* @param {string} expression The expression to test the regexp against.
* @returns {function(RegExp): boolean} True if the char matches the regexp. False otherwise.
*/
function createTestRegexpFunction(expression) {
return function (regexp) {
return regexp.test(expression);
};
}
export {
isLeftParenthesis,
isRightParenthesis,
isOperator,
isUnaryOperator,
isBinaryOperator,
isRightAssociative,
isLiteral,
isLiteralOrOperatorWithRightAssociativity,
getTokenTypeOf,
isSameTokenType,
isTypeOfLiteralOrParenthesis,
isOfTypeOperator
};
导入SymbolStringRepresentation
,TokenType
,OperatorType
,AssociativityType
已经使用TypeScript枚举重写(以前它们看起来像普通的JavaScript对象)。
创建一个像TokenizerUtilFunctions
这样的“ Package 器”类,并使所有这些函数都成为静态类方法,以保持将所有内容都 Package 在类(+接口,枚举)中的概念,这有意义吗(假设我开始使用TypeScript来提供更好的代码结构和可靠性)?还是保持原样,只为函数参数和返回值添加类型更好?
1条答案
按热度按时间x8diyxa71#
我会把他们留在课堂之外。
类方法不会被树摇动移除,而独立函数会。