草庐IT

javascript - json 格式的 jison 开始条件

coder 2025-02-13 原文

尽管在文档和论坛中进行了长时间的搜索,我仍然无法在 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 );'
>     ]]}

但不幸的是,没有人不提供完整的工作示例。

我试图排除两个标签之间的任何文本。在 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'); return 'EXTSTART';"]
            ,['$'                           , "return 'EOL';"]
        ]
    },  // end Lex rules

    "bnf": { // WARNING: only one space in between TOKEN ex: "STOP EOF"
        'data': [["EOL"      , "this.cmd='EMPTY'    ; return (this);"]           
           ,['EXTSTART INFO EXTEND EOL'  ,"this.cmd='EXTEN';this.value=$2;return (this);"]
           ]
    }};

  parser    = new jison(grammar);

  test= "\
    <extensions>\
      <opencpn:start></opencpn:start><opencpn:end></opencpn:end>\
      <opencpn:viz>1</opencpn:viz>\
     <opencpn:guid>714d1d6e-78be-46a0-af6e-2f3d0c505f6d</opencpn:guid>\
    </extensions>";

  data=parser.parse (test);

我当前的示例失败了

/node_modules/jison/node_modules/jison-lex/regexp-lexer.js:42 startConditions[conditions[k]].rules.push(i);

最佳答案

不幸的是,没有人回答我的问题:)

我不得不对 Jison Lexer 代码进行逆向工程以找出正确的语法。我想这可能对其他人有帮助,在答案之后:)

Jison 的词法条件在 JSON 语法下工作良好,但它们应该在名为 "startConditions" 的数组中预先声明,如下例所示。

grammar = { 
   "lex": {

       "startConditions" : { "INITIAL":"// Default initial Jison/Lex context"
            ,"MOD_EXT": "// extenstions context "
            ,"MOD_RTE": "// routes context"
        },

        "rules" : [['[\\n\\s]+' , "/* skip whitespace & new lines */"]
            // extensions blocs
            ,[['INITIAL'], '<extensions>'     , "this.begin('MOD_EXT');"]
            ,[['MOD_EXT'], '<\\/extensions>'  , "this.popState();"]
            ,[['MOD_EXT'], '[<>\\/\\-\\s\\n]', "/* ignore */"]
            ,[['MOD_EXT'], '[0-z]+'           , "/* ignore */"]
        Etc...

为了方便大家生活,这里先做一个简单的工作实例。

// Sample JISON start conditions with Jason syntax
var jison    = require("jison").Parser;

grammar = { 

    "lex": {
         "macros": {  // few usefull macro
            "slash": "\\/",
            "space": "\\s+",
            "quot" : "\\\'",
            "dquot": "\\\"",
            "dot"  : "\\.",
            "digit": "[0-9]",
            "int"  : "-?([0-9]+)",
            "float": "-?([0-9]*\\.[0-9]+)",
            "hexa" : "([0-9]|(a-h)|(A-H])+"
        },

       "startConditions" : { "INITIAL":"// Default initial Jison/Lex context"
            ,"MOD_EXT": "// extenstions context "
            ,"MOD_RTE": "// routes context"
        },

        "rules" : [['[\\n\\s]+' , "/* skip whitespace & new lines */"]
            // extensions blocs
            ,[['INITIAL'], '<extensions>'     , "this.begin('MOD_EXT');"]
            ,[['MOD_EXT'], '<\\/extensions>'  , "this.popState();"]
            ,[['MOD_EXT'], '[<>\\/\\-\\s\\n]', "/* ignore */"]
            ,[['MOD_EXT'], '[0-z]+'           , "/* ignore */"]

            // routes points blocs
            ,[['INITIAL'],'<rtept' , "this.begin('MOD_RTE'); return 'RTE_BEG';"]
            ,[['MOD_RTE'], '<\\/rtept>'       , "this.popState(); return 'RTE_END';"]
            ,[['MOD_RTE'], 'lat='             , "return 'LAT';"]
            ,[['MOD_RTE'], 'lon='             , "return 'LON';"]
            ,[['MOD_RTE'], '{float}'          , "return 'CARD';"]
            ,[['MOD_RTE'], '<name>'           , "return 'NAME_BEG';"]
            ,[['MOD_RTE'], '<\\/name>'        , "return 'NAME_END';"]
            ,[['MOD_RTE'], '<time>'           , "return 'TIME_BEG';"]
            ,[['MOD_RTE'], '<\\/time>'        , "return 'TIME_END';"]
            ,[['MOD_RTE'], '<sym>'            , "return 'SYM_BEG';"]
            ,[['MOD_RTE'], '<\\/sym>'         , "return 'SYM_END';"]
            ,[['MOD_RTE'], '<type>'           , "return 'TYPE_BEG';"]
            ,[['MOD_RTE'], '<\\/type>'        , "return 'TYPE_END';"]
            ,[['MOD_RTE'], '<extensions>'     , "this.begin('MOD_EXT');"]
            ,[['MOD_RTE'], '([0-z]|[-+])+\\b' , "return 'TEXT';"]
            ,[['MOD_RTE'], '[>{quot}{dquot}{space}]' , "// ignore"]

            // end of parsing buffer
            ,['$'                            , "return 'EOL';"]
        ]
    },  // end Lex rules

    "bnf": { // WARNING: only one space in between TOKEN ex: "STOP EOF"
        'data': [
            ["EOL"           ,  "return ('EMPTY');"]
           ,["ROUTEPOINTS EOL", "return (this.route);"]
           ]

        // handle multiple waypoints
         // A routepoint should at least have a LAT+LONG+NAME
        ,'ROUTEPOINTS' : [ // store all waypoint in an array
            ["ROUTEPOINT", "console.log('Parsing First Waypts=%j',this.waypts);this.route=[]; this.route.push(this.waypts);"]
           ,["ROUTEPOINTS ROUTEPOINT", "console.log('Parsing Next  Waypts=%j',this.waypts);;this.route.push(this.waypts);"]

        ]

        // A routepoint should at least have a LAT+LONG+NAME
        ,'ROUTEPOINT' :  [ // <rtept lat='47.542780648' lon='-2.896743643'>...
            ["RTE_BEG LATITUDE LONGITUDE DATE NAME SYM TYPE RTE_END", "this.waypts={lat:$2,lon:$3,name:$5,date:$4};"]
           ,["RTE_BEG LATITUDE LONGITUDE DATE NAME RTE_END", "this.waypts={lat:$2,lon:$3,name:$5,date:$4};"]
           ,["RTE_BEG LATITUDE LONGITUDE NAME RTE_END", "this.waypts={lat:$2,lon:$3,name:$4,date:'unknow'};"]
        ]  
        // lat='47.542780648'
        ,'LATITUDE'    : [["LAT CARD", "$$=$2;"]]          
        //  lon='-2.896743643'
        , 'LONGITUDE'  : [["LON CARD", "$$=$2;"]]
        //<time>2014-09-16T21:55:19Z</time>\
        , 'DATE'       : [["TIME_BEG TEXT TIME_END", "$$=$2;"]]
        // <name>001</name>\
        , 'NAME'       : [["NAME_BEG TEXT NAME_END", "$$=$2;"]]
        // <sym>001</name>\
        , 'SYM'        : [["SYM_BEG TEXT SYM_END", "//ignore"]]
        // <name>001</name>\
        , 'TYPE'       : [["TYPE_BEG TEXT TYPE_END", "//ignore"]]

    }};


  parser    = new jison(grammar);

  test= "\
    <extensions>\
        <opencpn:start></opencpn:start><opencpn:end></opencpn:end>\
        <opencpn:viz>1</opencpn:viz>\
        <opencpn:guid>714d1d6e-78be-46a0-af6e-2f3d0c505f6d</opencpn:guid>\
    </extensions>\
    <rtept lat='47.542780648' lon='-2.896743643'>\
        <time>2014-09-16T21:55:19Z</time>\
        <name>001</name>\
        <sym>diamond</sym>\
        <type>WPT</type>\
        <extensions>\
            <opencpn:guid>408c309c-6a8c-411d-815b-0c0054646d45</opencpn:guid>\
            <opencpn:viz>1</opencpn:viz>\
            <opencpn:viz_name>0</opencpn:viz_name>\
            <opencpn:auto_name>1</opencpn:auto_name>\
        </extensions>\
    </rtept>\
    <rtept lat='44.542780648' lon='-4.896743643'>\
        <time>2014-08-16T21:55:19Z</time>\
        <name>002</name>\
    </rtept>\
    <rtept lat='43.542780648' lon='-5.896743643'>\
        <name>003</name>\
    </rtept>\
    <rtept lat='48.542780648' lon='-3.896743643'>\
        <time>2014-10-16T21:55:19Z</time>\
        <name>004</name>\
        <sym>diamond</sym>\
        <type>WPT</type>\
        <extensions>\
            <opencpn:guid>408c309c-6a8c-411d-815b-0c0054646d45</opencpn:guid>\
            <opencpn:viz>1</opencpn:viz>\
            <opencpn:viz_name>0</opencpn:viz_name>\
            <opencpn:auto_name>1</opencpn:auto_name>\
        </extensions>\
    </rtept>";

  route=parser.parse (test);

  console.log ("\n\nMy GPX route's waypoints");
  for (var waypts in route) {
      console.log (" -- name: %s  Lon: %s Lat:%s Date:%s", route [waypts].name, route [waypts].lat, route [waypts].lon, route [waypts].date);
  };

  console.log ("done");

关于javascript - json 格式的 jison 开始条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25889540/

有关javascript - json 格式的 jison 开始条件的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  5. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  6. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  7. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  8. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  9. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  10. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

随机推荐