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,提问作者أنيسيتو روي
相关产品推荐
相关产品推荐

