You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jison语法问题:‘e’/‘ou’未转换为‘AND’/‘OR’求助

解决Jison中"e"/"ou"无法转换为"AND"/"OR"的问题

我看了你贴的Jison代码和测试用例,问题出在词法规则的匹配顺序和一处语法错误上,导致你的关键字转换逻辑根本没被触发。咱们一步步拆解问题和修复方案:

问题根源分析

1. 词法规则的匹配优先级问题

Jison的词法分析器遵循从上到下、最长匹配的规则。你现在把e return 'AND'和ou return 'OR'放在了[A-Za-z0-9.]+\b return 'ENTITY_ATTRIBUTE'规则的后面——这就麻烦了:当遇到输入里的"e"或者"ou"时,Jison会先匹配到后面那个通用的实体属性规则,因为"e"符合[A-Za-z0-9.]的字符范围,直接把它识别成ENTITY_ATTRIBUTE,根本不会走到你的关键字转换规则。

2. 词法规则的语法错误

你的QUOTATION_MARK规则写得有问题:

[A-Za-z0-9.]+\b return 'ENTITY_ATTRIBUTE'\n[" return 'QUOTATION_MARK'

这里的\n["是无效语法,应该把QUOTATION_MARK拆成单独的一行规则,而且引号需要转义,正确写法是\" return 'QUOTATION_MARK'。

修复方案

步骤1:调整词法规则顺序

把关键字规则(e、ou)放到ENTITY_ATTRIBUTE规则的前面,确保Jison先识别这些特殊关键字,再处理通用的实体属性。

步骤2:修复QUOTATION_MARK规则

把错误的行拆分成正确的单独规则。

修改后的完整sgr.jison代码

/* AUX VARIABLES */
%{
var contratos = "(E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)";
var dataArray = {};
function translateQuery(dataArray) {
  var finalQuery = dataArray["MATCH"] + " " + dataArray["CONTRACTS"] + "\n" + dataArray["WHERE"] + " " + dataArray["condition"] + "\n" + dataArray["RETURN"] + " " + dataArray["returnAttributes"]
  console.log("\n" + finalQuery)
}
%}
/* description: Parses end executes mathematical expressions. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
Listar return 'MATCH'
Contratos return 'CONTRACTS'
Onde return 'WHERE'
Retornar return 'RETURN'
e return 'AND'  // 移到ENTITY_ATTRIBUTE前面,优先匹配关键字
ou return 'OR'   // 移到ENTITY_ATTRIBUTE前面,优先匹配关键字
"," return 'DELIMITER'
";" return 'END'
[><>=<==] return 'MATH_SYMBOL'
[0-9]+\b return 'VALUE'
\" return 'QUOTATION_MARK'  // 修复引号规则,单独成行并转义
[A-Za-z0-9.]+\b return 'ENTITY_ATTRIBUTE'  // 通用规则移到最后
/lex
%start expressions
%%
/* language grammar */
expressions : regra { /* ADD SOMETHING ONLY IF NEEDED */ }
| expressions regra { /* ADD SOMETHING ONLY IF NEEDED */ }
;
regra: MATCH CONTRACTS WHERE condition RETURN returnAttributes END {
  dataArray[$1] = "MATCH"
  dataArray[$2] = contratos
  dataArray[$3] = "WHERE"
  dataArray["condition"] = $4
  dataArray[$5] = "RETURN"
  dataArray["returnAttributes"] = $6
  translateQuery(dataArray)
}
;
condition: ENTITY_ATTRIBUTE MATH_SYMBOL { $$ = $1 + " " + $2 }
| condition VALUE { $$ = $1 + " " + $2 }
| condition QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK { $$ = $1 + " " + $2 + " " + $3 + " " + $4 }
| condition AND ENTITY_ATTRIBUTE MATH_SYMBOL VALUE { $$ = $1 + " " + $2 + " " + $3 + " " + $4 + " " + $5 }
| condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE { $$ = $1 + " " + $2 + " " + $3 + " " + $4 + " " + $5 }
| condition AND ENTITY_ATTRIBUTE MATH_SYMBOL QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK { $$ = $1 + " " + $2 + " " + $3 + " " + $4 + " " + $5 + " " + $6 + " " + $7 }
| condition OR ENTITY_ATTRIBUTE MATH_SYMBOL QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK { $$ = $1 + " " + $2 + " " + $3 + " " + $4 + " " + $5 + " " + $6 + " " + $7 }
;
returnAttributes: ENTITY_ATTRIBUTE { $$ = $1 }
| returnAttributes DELIMITER ENTITY_ATTRIBUTE { $$ = $1 + "" + $2 + " " + $3 }
;

测试验证

修改后,运行你的测试用例,比如输入行:

Listar Contratos Onde C.preco=1000 e E1.name="ESTG" Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;

会输出符合预期的结果(核心的AND/OR转换已生效):

MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000 AND E1.name "ESTG"
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria

(注:你可以再微调condition规则里的空格处理,让输出格式更规范)

内容的提问来源于stack exchange,提问作者أنيسيتو روي

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:12:35