所以我通过JISON生成了一个解析器:
// mygenerator.js
var Parser = require("jison").Parser;
// a grammar in JSON
var grammar = {
"lex": {
"rules": [
["\\s+", "/* skip whitespace */"],
["[a-f0-9]+", "return 'HEX';"]
]
},
"bnf": {
"hex_strings" :[ "hex_strings HEX",
"HEX" ]
}
};
// `grammar` can also be a string that uses jison's grammar format
var parser = new Parser(grammar);
// generate source, ready to be written to disk
var parserSource = parser.generate();
// you can also use the parser directly from memory …
Run Code Online (Sandbox Code Playgroud) 在以前的Jison版本中,可以使用类似Flex的功能,允许在词法分析器和解析器上下文中定义变量,例如:
%{
var chars = 0;
var words = 0;
var lines = 0;
%}
%lex
%options flex
%%
\s
[^ \t\n\r\f\v]+ { words++; chars+= yytext.length; }
. { chars++; }
\n { chars++; lines++ }
/lex
%%
E : { console.log(lines + "\t" + words + "\t" + chars) ; };
Run Code Online (Sandbox Code Playgroud)
参考: Flex喜欢的功能?
虽然,在最新版本的Jison中,这是无效的.chars
,words
并且lines
无法从解析器上下文到达,生成错误.
在搜索有关新版本的更多信息时,我发现应该可以通过在解析器的上下文中定义输出%{ ... %}
,但它不起作用,尽管它用于多行语句.我正在生成从源代码到目标语言的代码,我将对这些代码进行美化,应用正确的缩进,由作用域控制并直接从解析器生成,而不构建AST.
全球定义目前如何在Jison中运作?
我正在使用Jison(Bison)来创建一个简单的标记语言.我显然对此很陌生,但略有不同的变化非常好.我只是不明白S/R冲突的根源.
"文本"由两个词法分析器操作(具有不同的"开始条件")返回似乎并不重要,我喜欢这样,因为它似乎允许语法具有更少的规则,并且因为给用户的错误消息是一致的.我已经尝试将"文本"规则放在一起,不管上下文如何,我也尝试给每个标记一个不同的名称,但它似乎对S/R冲突没有任何影响.
解析器是SUPPOSED用于创建具有纯文本,子数组和各种特殊节点的json对象.
规格:
/* lexical grammar */
%lex
%s bracketed
%%
<bracketed>(\\.|[^\\\,\[\]])+ { yytext = yytext.replace(/\\(.)/g, '$1'); return 'Text'; }
<INITIAL>(\\.|[^\\\[])+ { yytext = yytext.replace(/\\(.)/g, '$1'); return 'Text'; }
"[" { this.begin('bracketed'); return '['; }
"]" { this.popState(); return ']'; }
"," return ','
<<EOF>> return 'END'
/lex
%start template
%%
template
: sentence END
;
sentence
: /* empty */
| sentence Text
| sentence '[' ']'
| sentence '[' dynamic ']'
;
dynamic
: sentence
/*| dynamic …
Run Code Online (Sandbox Code Playgroud) 有没有人有一个简单的例子,说明如何使用Jison定义一个解析类似python的缩进的语法?
尽管在文档和论坛中进行了长时间的搜索,但仍然无法在node.js中使用JSON格式获得正确的Jison 启动条件语法
> ** Documentation at http://zaach.github.io/jison/docs/ says:
> // Using the JSON format, start conditions are defined with an array
> // before the rule’s
> matcher {rules:[
> [['expect'], '[0-9]+"."[0-9]+', 'console.log( "found a float, = " + yytext );'
> ]]}
Run Code Online (Sandbox Code Playgroud)
但遗憾的是,没有人不提供完整的工作样本.
我试图排除两个标签之间的任何文本.在lex中会使用开始条件.Jison文档说它应该有效.然而,由于Jison错误消息不是非常直观,我很乐意找到一个可行的样本来继续前进.
有人会有解决方案吗?
var jison = require("jison").Parser;
grammar = {
"lex": {
"rules" : [ [" +" , "/* skip whitespace */"]
,[['mode1'], '[0-z]+\\b' , "return 'INFO';"]
,[['mode1'], '<\\/extensions>' , "this.popState(); return 'EXTEND';"]
,['<extensions>' , "this.begin('mode1'); …
Run Code Online (Sandbox Code Playgroud) 我这里有一个JISON计算器示例的略微修改版本:
/* description: Parses end executes mathematical expressions. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
[0-9]+("."[0-9]+)?\b return 'NUMBER'
"*" return '*'
"/" return '/'
"-" return '-'
"+" return '+'
"^" return '^'
"!" return '!'
"%" return '%'
"(" return '('
")" return ')'
"PI" return 'PI'
"E" return 'E'
<<EOF>> return 'EOF'
. return 'INVALID'
/lex
/* operator associations and precedence */
%left '+' '-'
%left '*' '/'
%left '^'
%right '!'
%right …
Run Code Online (Sandbox Code Playgroud) 下面的代码片段上可以找到:http://zaach.github.io/jison/demos/calc/,也是jison文档页面。阅读 jison、lex 和 flex 文档后 - 我仍然不完全理解 %lex 和 /lex 语法。它特定于 jison 扫描仪生成器吗?意思是它提供稍后在文档中显示的 json 输出的唯一功能?我之所以这么问是因为 jison 文档没有明确解释其目的,而且 flex/lex 规则似乎不允许这种语法。
/* description: Parses end executes mathematical expressions. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
[0-9]+("."[0-9]+)?\b return 'NUMBER';
"*" return '*';
"/" return '/';
"-" return '-';
"+" return '+';
"^" return '^';
"(" return '(';
")" return ')';
"PI" return 'PI';
"E" return 'E';
<<EOF>> return 'EOF';
/lex
Run Code Online (Sandbox Code Playgroud) 我正在使用Jison构建一个简单的计算器语言,其中包含变量.我希望这些变量与JavaScript类似,即您必须var
首次使用关键字对其进行初始化.在我的语言中,如果变量重新初始化,我想显示错误.
var myVar = 4
var myVar = 3
// Error, cannot reinitialise variable myVar on line 2
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何获取AST节点的行号?在我的语法文件中,我可以将解析器中的行号传递给我的AssignVariable
对象,但我想知道是否有更好的方法来执行此操作?
stmt
: 'PRINT' expr
{ $$ = new yy.Print($2) }
| 'VAR' 'IDENTIFIER' 'ASSIGN' expr
{ $$ = new yy.AssignVariable($2, $4, $3); $$.lineNo = yylineno }
| 'IDENTIFIER' 'ASSIGN' expr
{ $$ = new yy.SetVariable($1, $3, $2) }
;
Run Code Online (Sandbox Code Playgroud)
我还需要编译器中其他节点的行号用于其他类型的错误检查.
从这个问题中得到的更高级别的内容可能是:使用Jison(或类似版本)检测和处理编译时错误的最佳方法是什么?
我正在Jison中编写一个简单的表达式解析器.这是我的语法:
{
"operators": [
["left", "+", "-"],
["left", "*", "/", "%"]
],
"bnf": {
"program": [
["statement EOF", "return $1;"]
],
"statement": [
["expression NEWLINE", "$$ = $1 + ';';"]
],
"expression": [
["NUMBER", "$$ = yytext;"],
["expression binary expression", "$$ = $1 + $2 + $3;"]
],
"binary": [
["+", "$$ = ' + ';"],
["-", "$$ = ' - ';"],
["*", "$$ = ' * ';"],
["/", "$$ = ' / ';"],
["%", "$$ = ' % ';"], …
Run Code Online (Sandbox Code Playgroud) 我正在使用Jison编写解析器.这是我的语法:
{
"program": [
["statements EOF", "return $1;"]
],
"statements": [
["statement", "$$ = $1;"],
["statements statement", "$$ = $1 + '\\n' + $2;"]
],
"statement": [
["expression NEWLINE", "$$ = $1 + ';';"]
],
"expression": [
["NUMBER", "$$ = yytext;"],
["expression expression", "$$ = $1 + ', ' + $2;"]
]
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我收到以下错误消息:
Conflict in grammar: multiple actions possible when lookahead token is NUMBER in
state 9
- reduce by rule: expression -> expression expression
- shift token (then …
Run Code Online (Sandbox Code Playgroud) jison ×10
javascript ×5
bison ×4
parsing ×4
flex-lexer ×1
grammar ×1
indentation ×1
node.js ×1