#javascript #parsing #parser-generator #jison
#javascript #синтаксический анализ #анализатор-генератор #jison
Вопрос:
Я создаю грамматику в 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», они должны возвращать «И» и «ИЛИ» соответственно.
Проблема в том, что когда я его тестирую, вместо того, чтобы возвращать мне «И» и «ИЛИ», он возвращает мне «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
Однако выходные данные:
Что я сделал не так?
Ответ №1:
Токены, идентифицированные в вашем лексическом анализаторе, имеют тип токена, который представляет собой строку, возвращаемую из действия сканирования, и соответствующий текст, который лексический сканер сохраняет в своем yytext
свойстве, из которого анализатор инициализирует семантическое значение токена. (Это не очень хорошо описано в документации.)
Итак, в этом действии:
condition:
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = $1 " "
$2 " "
$3 " "
$4 " "
$5
}
значение $2
— это текст, соответствующий токену, тип токена которого был "OR"
, то есть ou
. Если вам нужна строка "OR"
, это то, что вы должны были поместить в действие:
condition:
condition OR ENTITY_ATTRIBUTE MATH_SYMBOL VALUE
{
$$ = $1 " OR "
$3 " "
$4 " "
$5
}
(Сказав это, я должен сказать, что я думаю, что есть лучшие способы структурирования AST. Но если это работает для вас, это круто.)