Jison 没有假设正确的语法
Jison not assuming correct grammar
我正在用 jison 创建语法
这是我的jison文件:
sgr.jison
/*
AUX VARIABLES
*/
%{
var contratos = "(E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)";
var dataArray = {};
function
translateQuery(dataArray)
{
var finalQuery = dataArray["Listar"] + " "
+ dataArray["Contratos"] + "\n"
+ dataArray["Onde"] + " "
+ dataArray["condition"] + "\n"
+ dataArray["Retornar"] + " "
+ 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'
ou return 'OR'
"," return 'DELIMITER'
";" return 'END'
[><>=<==] return 'MATH_SYMBOL'
[0-9]+\b return 'VALUE'
[A-Za-z0-9.]+\b return 'ENTITY_ATTRIBUTE'
["] return 'QUOTATION_MARK'
/lex
%start expressions
%% /* language grammar */
expressions :
regra
{
/*
ADD SOMETHING
ONLY IF NEEDED
*/
}
| /* | significa um OU o que quer dizer que isto aqui pode ter mais do que uma regra ISTO E FEITO PELA RECURSIVIDADE*/
expressions regra
{
/*
ADD SOMETHING
ONLY IF NEEDED
*/
}
;
regra:
MATCH CONTRACTS
WHERE condition
RETURN returnAttributes END
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
dataArray[] = "MATCH"
dataArray[] = contratos
dataArray[] = "WHERE"
dataArray["condition"] =
dataArray[] = "RETURN"
dataArray["returnAttributes"] =
/*ESTA FUNCAO TRATA DE TRADUZIR A QUERY QUE E INTERPRETADA*/
translateQuery(dataArray)
}
;
condition:
ENTITY_ATTRIBUTE MATH_SYMBOL
{
$$ = + " "
+
}
|
condition VALUE
{
$$ = + " "
+
}
|
condition QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK
{
$$ = + " "
+ + " "
+ + " "
+
}
|
condition AND ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+
}
|
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+
}
|
condition AND ENTITY_ATTRIBUTE MATH_SYMBOL QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+
}
|
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+
}
;
returnAttributes:
ENTITY_ATTRIBUTE
{
$$ =
}
|
returnAttributes DELIMITER ENTITY_ATTRIBUTE
{
$$ = + ""
+ + " "
+
}
;
在我的词汇语法定义中我有:
e return 'AND'
ou return 'OR'
因此,无论何时在我的测试文件中找到“e”或“ou”,它们都应该分别 return“AND”和“OR”。
问题是,当我测试它时,不是 return给我“AND”和“OR”,而是 return给我“e”和“ou”。
看看:
这是我的测试文件:
test.sgr
Listar Contratos
Onde C.preco=1000
Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde C.preco=1000 e E1.name="ESTG"
Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde C.preco=1000 e E1.name="ESTG" e C.TipoProcedimento="ADS"
Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde E1.name="ESTG"
Retornar E1.name,C.Preco,C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde E1.name="ESTG" e C.preco=1000 ou C.preco>1000
Retornar E1.name,C.Preco,C.NifAdjudicante,C.NifAdjudicataria;
输出应该是:
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000 AND E1.name = " ESTG "
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000 AND E1.name = " ESTG " AND C.TipoProcedimento = " ADS "
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE E1.name = " ESTG "
RETURN E1.name, C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE E1.name = " ESTG " AND C.preco = 1000 OR C.preco > 1000
RETURN E1.name, C.Preco, C.NifAdjudicante, C.NifAdjudicataria
但是输出是:
我做错了什么?
在您的词法分析器中识别的标记具有 标记类型,这是您从扫描器操作中 return 得到的字符串,以及匹配的文本,词法扫描器保留在其 yytext
属性 中,解析器从中初始化标记的语义值。 (这在文档中没有很好地描述。)
所以在这个动作中:
condition:
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+
}
</code>的值为<code>"OR"
的token匹配的文本,即ou
。如果您想要字符串 "OR"
,那么您应该将其放入操作中:
condition:
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " OR "
+ + " "
+ + " "
+
}
(话虽如此,我不得不说我认为有更好的方法来构建 AST。但是如果这个对你有用,那就太棒了。)
我正在用 jison 创建语法
这是我的jison文件:
sgr.jison
/*
AUX VARIABLES
*/
%{
var contratos = "(E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)";
var dataArray = {};
function
translateQuery(dataArray)
{
var finalQuery = dataArray["Listar"] + " "
+ dataArray["Contratos"] + "\n"
+ dataArray["Onde"] + " "
+ dataArray["condition"] + "\n"
+ dataArray["Retornar"] + " "
+ 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'
ou return 'OR'
"," return 'DELIMITER'
";" return 'END'
[><>=<==] return 'MATH_SYMBOL'
[0-9]+\b return 'VALUE'
[A-Za-z0-9.]+\b return 'ENTITY_ATTRIBUTE'
["] return 'QUOTATION_MARK'
/lex
%start expressions
%% /* language grammar */
expressions :
regra
{
/*
ADD SOMETHING
ONLY IF NEEDED
*/
}
| /* | significa um OU o que quer dizer que isto aqui pode ter mais do que uma regra ISTO E FEITO PELA RECURSIVIDADE*/
expressions regra
{
/*
ADD SOMETHING
ONLY IF NEEDED
*/
}
;
regra:
MATCH CONTRACTS
WHERE condition
RETURN returnAttributes END
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
dataArray[] = "MATCH"
dataArray[] = contratos
dataArray[] = "WHERE"
dataArray["condition"] =
dataArray[] = "RETURN"
dataArray["returnAttributes"] =
/*ESTA FUNCAO TRATA DE TRADUZIR A QUERY QUE E INTERPRETADA*/
translateQuery(dataArray)
}
;
condition:
ENTITY_ATTRIBUTE MATH_SYMBOL
{
$$ = + " "
+
}
|
condition VALUE
{
$$ = + " "
+
}
|
condition QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK
{
$$ = + " "
+ + " "
+ + " "
+
}
|
condition AND ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+
}
|
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+
}
|
condition AND ENTITY_ATTRIBUTE MATH_SYMBOL QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+
}
|
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL QUOTATION_MARK ENTITY_ATTRIBUTE QUOTATION_MARK
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+
}
;
returnAttributes:
ENTITY_ATTRIBUTE
{
$$ =
}
|
returnAttributes DELIMITER ENTITY_ATTRIBUTE
{
$$ = + ""
+ + " "
+
}
;
在我的词汇语法定义中我有:
e return 'AND'
ou return 'OR'
因此,无论何时在我的测试文件中找到“e”或“ou”,它们都应该分别 return“AND”和“OR”。
问题是,当我测试它时,不是 return给我“AND”和“OR”,而是 return给我“e”和“ou”。
看看:
这是我的测试文件:
test.sgr
Listar Contratos
Onde C.preco=1000
Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde C.preco=1000 e E1.name="ESTG"
Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde C.preco=1000 e E1.name="ESTG" e C.TipoProcedimento="ADS"
Retornar C.Preco, C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde E1.name="ESTG"
Retornar E1.name,C.Preco,C.NifAdjudicante,C.NifAdjudicataria;
Listar Contratos
Onde E1.name="ESTG" e C.preco=1000 ou C.preco>1000
Retornar E1.name,C.Preco,C.NifAdjudicante,C.NifAdjudicataria;
输出应该是:
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000 AND E1.name = " ESTG "
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE C.preco = 1000 AND E1.name = " ESTG " AND C.TipoProcedimento = " ADS "
RETURN C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE E1.name = " ESTG "
RETURN E1.name, C.Preco, C.NifAdjudicante, C.NifAdjudicataria
MATCH (E1:ENTIDADE)-[C:CONTRATO] -> (E2:ENTIDADE)
WHERE E1.name = " ESTG " AND C.preco = 1000 OR C.preco > 1000
RETURN E1.name, C.Preco, C.NifAdjudicante, C.NifAdjudicataria
但是输出是:
我做错了什么?
在您的词法分析器中识别的标记具有 标记类型,这是您从扫描器操作中 return 得到的字符串,以及匹配的文本,词法扫描器保留在其 yytext
属性 中,解析器从中初始化标记的语义值。 (这在文档中没有很好地描述。)
所以在这个动作中:
condition:
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " "
+ + " "
+ + " "
+ + " "
+
}
</code>的值为<code>"OR"
的token匹配的文本,即ou
。如果您想要字符串 "OR"
,那么您应该将其放入操作中:
condition:
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = + " OR "
+ + " "
+ + " "
+
}
(话虽如此,我不得不说我认为有更好的方法来构建 AST。但是如果这个对你有用,那就太棒了。)