首页 > 解决方案 > 吉森没有假设正确的语法

问题描述

我正在用 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
        {
            $$ = $1 + " "
                + $2 + " "
                + $3 + " "
                + $4 + " "
                + $5 + " "
                + $6 + " "
                dataArray[$1] = "MATCH"
                dataArray[$2] = contratos
                dataArray[$3] = "WHERE"
                dataArray["condition"] = $4
                dataArray[$5] = "RETURN"
                dataArray["returnAttributes"] = $6
                /*ESTA FUNCAO TRATA DE TRADUZIR A QUERY QUE E INTERPRETADA*/
                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
        }
 ;

在我的词汇语法定义中,我有:

e     return 'AND'
ou    return 'OR'

因此,每当在我的测试文件中找到“e”或“ou”时,它们应该分别返回“AND”和“OR”。

问题是,当我测试它时,它不是返回我“AND”和“OR”而是返回我“e”和“ou”。

看一看:

这是我的测试文件:

测试.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

但是输出是:

输出

我做错了什么?

标签: javascriptparsingparser-generatorjison

解决方案


在词法分析器中识别的标记有一个标记类型,它是您从扫描器操作返回的字符串,以及匹配的文本,词法扫描器将其保存在yytext解析器初始化标记的语义值的属性中。(这在文档中描述得不是很好。)

所以在这个动作中:

condition:
    condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
        {
            $$ = $1 +  " "
               + $2 + " "
               + $3 + " "
               + $4 + " "
               + $5
        }

的值$2是与标记类型为 的标记匹配的文本"OR",即ou。如果您想要 string "OR",那么您应该将其放入操作中:

condition:
    condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
        {
            $$ = $1 + " OR "
               + $3 + " "
               + $4 + " "
               + $5
        }

(话虽如此,我不得不说我认为有更好的方法来构建 AST。但如果这个方法适合你,那就太酷了。)


推荐阅读