首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用javascript编写的搜索表达式解析器

编写一个搜索表达式解析器可以帮助你解析和处理用户输入的搜索查询。这个解析器可以支持基本的逻辑操作符(如 AND、OR、NOT)以及括号来分组表达式。以下是一个简单的 JavaScript 实现示例。

1. 定义搜索表达式解析器

我们将使用递归下降解析器来解析搜索表达式。这个解析器将支持以下操作符:

  • AND:逻辑与
  • OR:逻辑或
  • NOT:逻辑非
  • 括号 ():用于分组

2. 实现解析器

以下是一个简单的 JavaScript 实现:

代码语言:javascript
复制
class SearchExpressionParser {
    constructor(expression) {
        this.expression = expression;
        this.index = 0;
    }

    parse() {
        this.tokens = this.tokenize(this.expression);
        return this.parseExpression();
    }

    tokenize(expression) {
        const regex = /\s*(=>|&&|\|\||!|\(|\)|\w+)\s*/g;
        return expression.match(regex).map(token => token.trim());
    }

    parseExpression() {
        let left = this.parseTerm();

        while (this.peek() === 'OR') {
            this.consume('OR');
            const right = this.parseTerm();
            left = { type: 'OR', left, right };
        }

        return left;
    }

    parseTerm() {
        let left = this.parseFactor();

        while (this.peek() === 'AND') {
            this.consume('AND');
            const right = this.parseFactor();
            left = { type: 'AND', left, right };
        }

        return left;
    }

    parseFactor() {
        if (this.peek() === 'NOT') {
            this.consume('NOT');
            const operand = this.parseFactor();
            return { type: 'NOT', operand };
        } else if (this.peek() === '(') {
            this.consume('(');
            const expression = this.parseExpression();
            this.consume(')');
            return expression;
        } else {
            return this.parseLiteral();
        }
    }

    parseLiteral() {
        const token = this.consume();
        return { type: 'LITERAL', value: token };
    }

    peek() {
        return this.tokens[this.index];
    }

    consume(expected) {
        const token = this.tokens[this.index];
        if (expected && token !== expected) {
            throw new Error(`Expected ${expected} but found ${token}`);
        }
        this.index++;
        return token;
    }
}

// 示例用法
const expression = "NOT (apple AND orange) OR banana";
const parser = new SearchExpressionParser(expression);
const ast = parser.parse();
console.log(JSON.stringify(ast, null, 2));

3. 解释解析器

  • tokenize 方法:将输入的表达式字符串分割成标记(tokens)。使用正则表达式匹配操作符、括号和字面量。
  • parseExpression 方法:解析 OR 表达式。
  • parseTerm 方法:解析 AND 表达式。
  • parseFactor 方法:解析 NOT 表达式和括号分组。
  • parseLiteral 方法:解析字面量(如单词)。
  • peek consume 方法:用于查看和消费当前标记。

4. 生成的 AST(抽象语法树)

解析器将输入的表达式解析为一个抽象语法树(AST)。例如,输入 "NOT (apple AND orange) OR banana" 将生成以下 AST:

代码语言:javascript
复制
{
  "type": "OR",
  "left": {
    "type": "NOT",
    "operand": {
      "type": "AND",
      "left": {
        "type": "LITERAL",
        "value": "apple"
      },
      "right": {
        "type": "LITERAL",
        "value": "orange"
      }
    }
  },
  "right": {
    "type": "LITERAL",
    "value": "banana"
  }
}

5. 扩展和使用

你可以扩展这个解析器以支持更多的操作符或功能。解析后的 AST 可以用于进一步的处理,例如执行搜索查询或生成 SQL 查询。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

PE解析器编写(一)——总体说明

之前自己学习了PE文件格式,后来自己写了个PE文件解析器,这段时间工作上刚好要用到它,老板需要能查看某个exe中加载dll一个工具,我在使用之前自己写这个东西时候,发现很多东西都忘记了,所以...简单从RVA到Frva计算 工具主要采用MFC框架作为界面,pe文件解析部分完全由自己编写,主要使用了Windows中定义一些结构体。...两侧显示pe文件基本信息,比如文件头部中信息,文件OEP,基地址等等,右侧提供一个根据RVA计算它在文件中偏移功能,工具可以显示数据目录表信息和节表信息。...以上是程序主要功能,下面说下程序各个模块组成: 这个是工具中主要对话框资源,从上到下依次是关于(这个是MFC自己生成,我只是将它版本信息作了修改)、显示数据目录表信息对话框,它对应是第三个图...pe文件中各种信息类,这样整体类视图如下: 到此,我对这个工具中模块作了简单说明,后面会一一讲解各个部分实现。

1.2K20

为什么我 JavaScript编写 CSS

作为替代,我 JavaScript 编写了所有的 CSS。 我知道你在想什么:“为什么有人会用 JavaScript 编写 CSS 呢?!” 这篇文章我就来解答这个问题。...开发者们已经创建了不同风格 CSS-in-JS。迄今为止最受欢迎,是我和他人共同开发一个叫做 styled-components 库,在 GitHub 上有超过 20,000 颗星。...我可以在不产生任何意外后果情况下,添加、更改和删除 CSS。我对组件样式更改不会影响其他任何内容。如果删除组件,我也会删除它 CSS。不再是只增不减样式表了!...CSS-in-JS 还提供 CSS 预处理器所有重要功能。所有库都支持 auto-prefixing,JavaScript 原生提供了大多数其他功能,如 mixins(函数)和变量。...如果你使用 JavaScript 框架来构建包含组件 Web 应用程序,那么 CSS-in-JS 可能非常适合。特别是你所在团队中每个人都理解基本 JavaScript

1.3K50
  • MySQL(三)正则表达式搜索

    正则表达式是用来匹配文本特殊串(字符集合),将一个模式(正则表达式)与一个文本串进行比较; 所有种类程序设计语言、文本编辑器、操作系统等都支持正则表达式,正则表达式正则表达式语言来建立; MySQL...column包含文本1000所有行;它告诉MySQL:regexp后所跟东西作为正则表达式(与文字正文1000匹配一个正则表达式)处理。...例如:找出一个以一个数(包括小数点开始数)开始所有数值,简单搜索[0-9\\.]或([[:digit:]\\.])不行,因为它将在文本内任意位置查找匹配,可以使用^定位符,如下 select column...from table where column regexp '^[0-9\\.]' order by column; ^匹配串开始,有两种用法: ①在集合中([和]定义),用它来否定该集合 ②用来指串开始处...使regexp和like起相同作用:like匹配整串二regexp匹配子串,可以利用定位符,^开始每个表达式$结束每个表达式,就可以使regexp和like作用一样

    97710

    JavaScript实现二叉搜索

    不断此过程继续处理值 6,4,7,14 和 13。此二叉搜索深度为 3,表示距离根最远节点是三个节点。...我还添加了一些方便方法,size(),toArray()和toString(),它们对 JavaScript 很有用。 要掌握使用二叉搜索方法,最好从 contains() 方法开始。...关于此实现说明:始终有序前驱替换节点可能导致不平衡树,其中大多数值会位于树一侧。不平衡树意味着搜索效率较低,因此在实际场景中应该引起关注。...在二叉搜索树实现中,要确定是有序前驱还是有序后继以使树保持适当平衡(通常称为自平衡二叉搜索树)。...这个二叉搜索树实现完整源代码可以在我GitHub 中【http://github.com/nzakas/computer-science-in-javascript/】中找到。

    60710

    PE解析器编写(三)——区块表解析

    PE文件中所有节属性都被定义在节表中,节表由一系列IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构排列顺序和它们描述节在文件中排列顺序是一致。...区块表结构为IMAGE_SECTION_HEADER,在PE文件中存在一个该结构数组,用来保存各个区块信息,这个数组大小在PE头结构 IMAGE_NT_HEADERS 成员NumberOfSections...PE头结构后面的,所以我们只要知道OptionHeader结构指针,然后加上这个结构大小就可以获取到区块表地址,上面的代码也是这样做,首先获取了FileHeader指针,这个结构中SizeOfOptionalHeader...或者更简单方式是利用PE文件头地址 + 文件头大小也一样可以获取到区块表地址 void CPeFileInfo::InitSectionTable() { if (!...在这份代码中我们首先利用FileHeaderNumberOfSections成员获取区块表个数,然后在循环中以这个个数作为条件,以此往后寻址,将信息写入到对应数组中,最后在输出时候只需要根据需求输出我们感兴趣内容即可

    70320

    PE解析器编写(四)——数据目录表解析

    + 区块大小也就说明这个RVA是处在这个区块中,这样我们就找到RVA所在区块,RVA - 区块起始地址就得到它在区块中偏移,这个偏移加上区块在文件中首地址,得到就是RVA对应在文件中偏移,...RVA,第二个是这个表结构大小,在这个解析器中,主要显示这两项,同时为了方便在文件中查看,我们新加了一项,就是它在文件中偏移 在这个解析器代码中,我们定义了一个结构来存储这些信息 struct...这个跟dll加载有关,由OriginalFirstThunk指向结构是一个固定值,不会被重写值,一般它里面保存是函数名称,而由FirstThunk 保存结构一般是由PE解析器进行重写,PE...装载器首先搜索 OriginalFirstThunk ,找到之后加载程序迭代搜索数组中每个指针,找到每个 IMAGE_IMPORT_BY_NAME 结构所指向输入函数地址,然后加载器用函数真正入口地址来替代由...首先在名称表中遍历所有函数名称,然后在对应序号表中找到对应序号,我在这个解析器中显示出序号与Windows显示给外界序号相同,但是在pe文件内部,在进行寻址时使用是这个序号 - base值,

    1.6K20

    编写可维护JavaScript

    3.所有包含文档化方法对象 三、语句和表达式 A.花括号对齐方式 1.所有的块语句都应当使用花括号,包括:if、for、while、do...while......CSS表达式(IE9已经删除) C.将CSS从JavaScript中抽离 1.操作CSSclassName来修改元素样式,而不是直接xxx.style.color=‘red’或xxx.style.cssText...当两次发错误时,将有助于解决问题 2.如果正在编写代码,思考一下“我希望【某些事情】不会发生,如果发生,我代码会一团糟糕”。...这时,如果“某些事情 ”发生,就抛出一个错误 3.如果正在编写代码别人(不知道是谁)也会使用,思考一下他们使用方式,在特定情况下抛出错误 E.try-catch语句 1.try中retrun会等到...编码风格指南 附录B.JavaScript工具集

    85210

    编写可测试JavaScript代码

    编写可测试JavaScript代码 既然要对代码进行测试,那么为什么不让这一过程变得尽可能简单和轻松呢?JavaScript客户端代码测试之所以尤其困难,是因为我们几乎无法控制代码运行环境。...多种类型操作系统、多个版本操作系统、多种类型浏览器、多个版本浏览器,更不用说插件、扩展、多语言版本和缩放大小了,还有一些未知内容,所有这些因素交织在一起,阻碍着应用程序性能。...服务端JavaScript给了我们更多控制权,以便我们能够从总体上控制执行环境。然而,Rhino和Node.js应用程序不像其他语言一样有完整成熟工具、测试程序以及生态系统。...此外,Node.js异步特性也使得测试变得更加复杂。有趣是,这样一种与异步执行密切相关语言,竟然没有设置与该执行模式相配内置支持。...无论如何,测试——尤其是JavaScript测试——是很复杂。克服这种复杂性最好办法是完全控制自己实际所控制东西:代码。

    42700

    编写可测试JavaScript代码

    一、可测试JavaScript A.现有技术 1.敏捷开发 ①使用敏捷开发,并不一定意味着应用程序完成得更快且质量更高,敏捷开发最大优势是它处理需求变更方式。...②快速迭代和持续交互可以加快高质量软件交付。 2.测试驱动开发 在编写代码之前先编写测试,这些测试提供了必须遵循预期功能代码,编写测试失败后,接着开始编写代码,以便确保测试能够通过。...B.代码是让人 1.我们编写代码不是让电脑,而是让人 2.为何要编写可测试代码 可测试代码更加容易测试,意味着它更加容易维护,易维护则意味着它有让人(包括自己)更加容易理解 ,更加容易维护...2.依赖注入器可以为代码构建和注入完全成型对象。 J.注释 1.对于可测试JavaScript,所有即将要测试函数或方法前面都有相应注释。...E.运行客户端JavaScript单元测试 1.PhantomJS 2.Selenium F.运行服务器端JavaScript单元测试 1.jasmine 五、代码覆盖率 为代码覆盖率信息构建相应JS

    1.3K30

    PE文件解析器编写(二)——PE文件头解析

    之前在学习PE文件格式时候,是通过自己查看各个结构,自己一步步计算各个成员在结构中偏移,然后在计算出其在文件中偏移,从而找到各个结构值,但是在使用C语言编写这个工具时候,就比这个方便多,只要将对应指针类型转化为各个结构类型...这次主要说明是PE文件头解析,也就是之前看到第一个界面中显示内容,这个部分涉及到CPeFileInfo这个解析类部分代码,以及CPeFileInfoDlg这个对话框类代码。...hInstance //所在模块句柄 lpstrFile //用来保存用户选择文件路径缓冲 nMaxFile //缓冲区大小 lpstrTitle //这个对话框标题 Flags//对话框标识...,具体标识请查看MSDN,一般我们这样几个就足够了 一般只需要更改标题,内存缓冲区指针和它大小,其余按照上面的代码默认就好 用户选择后,将用户选择文件全路径显示出来,并调用CPefileInfo...则保存真正PE头所在偏移 所在获取DOS头时候简单将前面的几个字节转化为这个结构即可,在寻址PE头时候e_lfanew成员加上文件起始地址就可以得到PE头地址。

    1.3K20

    怎样编写更好 JavaScript 代码

    作者:Ryland G 翻译:疯狂技术宅 来源:dev.to ? 我看到没有多少人谈论改进 JavaScript 代码实用方法。以下是我用来编写更好 JS 一些顶级方法。...Promise 允许你编写异步逻辑,同时避免以前基于回调代码嵌套问题困扰。...const 是更严格限制和 “永固”,通常会产生更好代码。我仅有 1/20 变量 let 声明,其余都是 const。... for 循环进行顺序执行情况是比较罕见,但它们无法保证循环可分离性: let runningTotal = 0; for (let i = 0; i < myArray.length; i +...因此,任何语言编写高端代码一个关键就是具有一致和合理风格。由于 JS 生态系统广度,有许多针对 linter 和样式细节选项。

    1.3K30

    IntelliJ 搜索和全局搜索怎么

    要在 IntelliJ 中进行搜索,我们最常想到就是 Ctrl + F。 其实这个快捷键在 IntelliJ 中是在当前打开文本中进行搜索,如果我们希望进行全局搜索应该怎么呢?...如果你尝试搜索文字时候,你可能会发现,如果你需要内容在代码里面,这个搜索没有任何显示结果。 你只需要注意: 双击 Shift 搜索界面只会搜索名字。这个名字包括有文件名,操作名字等。...如果你有字符串在文件内,这个搜索是搜不到。但是非常好用是,你可以这个搜索搜索 IntelliJ 快捷键。...例如,你可以输入 push 然后搜索, 你可以看到界面中会显示 push 快捷键。 Ctrl + Shift + F 这个就是我们常用全文搜索了。...你可以对搜索内容有些过滤,比如说只搜索特定文件扩展名等。 这个就是全文搜索了。 请注意不要和双击 Shift 混淆了,搜索内容不一样。

    2K50

    教你一招:70 行 Python 代码编写一个递归下降解析器

    3个月前,我写了一篇文章,详细讲述了解析库编写计算器过程。然而,读者们普遍反应,他们对于见到一个从头开始写并且除了电池以外别无他物计算器更感兴趣。我想,为什么不呢?...写一个计算机很简单,如果你使用针对算术表达式hacks的话。但是hacks产生后果也几乎总是一样:解决方案不够优雅,不可扩展,并且很难直观理解。...我喜欢挑战,并且打算发一个有益帖子,所以我决定通用递归下降解析器来写它。本着与上次相同精神,我打算用尽可能少行数来干这件事,所以它充满了hacks和tricks。...我希望当你读完后你能更好理解如何解析内部工作,启发你适当解析库,以避免混乱。 要理解这篇文章,你应该很好理解Python,建议你要了解一些它是怎么解析,它是用来干什么。...一些LL解析器选择修正树里面的关联性。这样需要编写多行代码;)。这个不采纳,我们需要使它扁平化。

    1.2K100

    基础|如何优雅编写JavaScript代码

    提高自身编码能力和编写易于阅读和维护代码,是广大码农们提高开发效率和职业身涯中必做事情。 那么究竟如何编写出可维护、优雅代码呢?...编写简洁 JavaScript 代码 以下这些准则来自 Robert C. Martin 书 “Clean Code”,适用于 JavaScript。...整个列表很长,我选取了我认为最重要一部分,也是我在项目最多一部分,但是还是推荐大家看一下原文: https://github.com/ryanmcdermott/clean-code-javascript...当函数需要做更多事情时,它们将会更难进行编写、测试、理解和组合。 当你能将一个函数抽离出只完成一个动作,他们将能够很容易进行重构并且你代码将会更容易阅读。...且只用一个 service 完成这一需求。 bad 示例: good 示例:  避免条件判断 这看起来似乎不太可能。 大多人听到这第一反应是:“怎么可能不用 if 完成其他功能呢?”

    58030

    使用 JavaScript 编写更好条件语句

    在这篇文章中,我们将探索JavaScript中所谓条件语句如何工作。 如果你使用JavaScript工作,你将写很多包含条件调用代码。...这是一个编写更清晰、易理解和维护代码方法,不是吗? 2. 提前退出 / 提前返回 这是一个精简你代码非常酷技巧。我记得当我开始专业工作时,我在第一天学习使用提前退出来编写条件。...让我们在之前例子上添加更多条件。包含确定属性对象替代简单字符串动物。...想象如果代码有更复杂逻辑会怎么样?大量if..else语句。 我们能用三元运算符、&&条件等语法重构上面的功能,但让我们多个返回语句编写更清晰代码。...使用可选链和空值合并 这有两个为编写更清晰条件语句而即将成为 JavaScript 增强功能。当写这篇文章时,它们还没有被完全支持,你需要使用 Babel 来编译。

    1.6K30

    负责任编写JavaScript(一)

    当我们构建一个 WEB 应用程序时,必须要注意:我们正在安装模块可能会带来数百(甚至数千)个依赖,其中一些甚至不确定是不是安全[5]。我们还要编写复杂配置来打包。...请仔细考虑这样构建方式以及客户端路由是否真的有必要。通常情况下,能不用就不用。 如果担心导航性能,可以 rel = prefetch 来预加载同源文档。...当我们 Service workers 预缓存路由[18]时,我们将获得与链接预加载相同好处,但是对请求和响应控制程度更高。...我对 JavaScript 持批判态度,或许更准确地说,我对于把 JavaScript 作为构建 WEB 首要手段趋势持批判态度。...co=GENIE.Platform%3DAndroid&hl=en [17] Service workers: https://adactio.com/articles/13796 [18] Service

    75850

    Javascript编写帝国建筑游戏

    概述 描述 Civitas是一个在javascript帮助下Javascript编写帝国建筑游戏。 特征 超过80种类型建筑物,每个都在生产链中交织在一起。...定制气候区,每个区都有特定建筑物。 全球市场,玩家可以与其他定居点进行商品交易。 军队!海军!士兵!船舶! 成名系统,让您城市通过贸易,征服和特殊建筑升级。 影响外交威望体系。...排名屏幕,根据城市在世界上状态排名。 宣战,提出联盟和协议,要求其他定居点加入你城市,提出停火。 英雄,独特类和物品,属性。...播放 在开发过程中,Civitas使用了Bluebyte拥有版权几种资产,因此我无法通过游戏重新分发这些资产。您可以在此问题中找到指向所述资产链接。...此分享源代码和文章是小编在项目中、学习中整理一些认为不错项目。用户产生一些自愿下载或者付费行为。

    60840
    领券