简体   繁体   English

有没有办法用json编写解析逻辑?

[英]Is there any way to write parsing logic using json?

I have a map in java Map<String,Object> dataMap whose content looks like this -我在 java Map<String,Object> dataMap 中有一张地图,其内容如下所示 -

{country=Australia, animal=Elephant, age=18}

Now while parsing the map the use of various conditional statements may be made like-现在,在解析地图时,可以使用各种条件语句,例如-

if(dataMap.get("country").contains("stra")

OR

if(dataMap.get("animal") || 100 ==0)

OR

Some other operation inside if

I want to create a config file that contains all the rules on how the data inside the Map should look like.我想创建一个配置文件,其中包含有关 Map 内部数据外观的所有规则。 In simple words, I want to define the conditions that value corresponding to keys country, animal, and age should follow, what operations should be performed on them, all in the config file, so that the if elses and extra code can be removed.简单来说,我想定义key country、animal、age对应的value应该遵循的条件,对它们进行什么操作,都在config文件中,这样就可以去掉if else和多余的代码。 The config file will be used for parsing the map.配置文件将用于解析地图。

Can someone tell me how such a config file can be written, and how can it be used inside Java?有人可以告诉我如何编写这样的配置文件,以及如何在 Java 中使用它? Sample examples and code references will be of help.示例示例和代码参考将有所帮助。

I am thinking of creating a json file for this purpose我正在考虑为此创建一个 json 文件

Example -例子 -

Boolean b = true;
        List<String> conditions = new ArrayList<>();
        if(dataMap.get("animal").toString().contains("pha")){
            conditions.add("condition1 satisifed");
            if(((Integer.parseInt(dataMap.get("age").toString()) || 100) ==0)){
                conditions.add("condition2 satisifed");
                if(dataMap.get("country").equals("Australia")){
                    conditions.add("condition3 satisifed");
                }
                else{
                    b=false;
                }
            }
            else{
                b=false;    
            }
        }
        else{
            b=false;
        }

Now suppose I want to define the conditions in a config file for each map value like the operation ( equals, OR, contains) and the test values, instead of using if else's.现在假设我想在配置文件中为每个映射值定义条件,例如操作(等于、OR、包含)和测试值,而不是使用 if else 的。 Then the config file can be used for parsing the java map然后配置文件就可以用来解析java map

Just to manage expectations: Doing this in JSON is a horrible, horrible idea.只是为了管理期望:在 JSON 中这样做是一个可怕的想法。

To give you some idea of what you're trying to make:为了让您了解您正在尝试制作的内容:

Grammars like this are best visualized as a tree structure.像这样的语法最好可视化为树结构。 The 'nodes' in this tree are:这棵树中的“节点”是:

  • 'atomics' ( 100 is an atom, so is "animal" , so is dataMap ). 'atomics'( 100是一个原子,所以是"animal" ,也是dataMap )。
  • 'operations' ( + is an operation, so is or / || ). '操作'( +是一个操作,所以是or / || )。
  • potentially, 'actions', though you can encode those as operations.可能是“动作”,但您可以将它们编码为操作。

Java works like this, so do almost all programming languages, and so does a relatively simple 'mathematical expression engine', such as something that can evaluate eg the string "(1 + 2) * 3 + 5 * 10" into 59 . Java 是这样工作的,几乎所有的编程语言也是如此,一个相对简单的“数学表达式引擎”也是如此,例如可以将字符串"(1 + 2) * 3 + 5 * 10"59

In java, dataMap.get("animal") || 100 ==0在java中, dataMap.get("animal") || 100 ==0 dataMap.get("animal") || 100 ==0 is parsed into this tree: dataMap.get("animal") || 100 ==0被解析成这棵树:

           OR operation
         /             \
  INVOKE get[1]         equality
   /       \            /       \
dataMap   "animal"    INT(100)  INT(0)

where [1] is stored as INVOKEVIRTUAL java.util.Map :: get(Object) with as 'receiver' an IDENT node, which is an atomic, with value dataMap , and an args list node which contains 1 element, the string literal atomic "animal" , to be very precise.其中 [1] 存储为 INVOKEVIRTUAL java.util.Map :: get(Object)与作为 'receiver' 的 IDENT 节点,它是一个原子,值为dataMap ,和一个包含 1 个元素的 args 列表节点,字符串文字原子"animal" ,非常准确。

Once you see this tree you see how the notion of precedence works - your engine will need to be capable of representing both (1 + 2) * 3 as well as 1 + (2 * 3) , so doing this without trees is not really possible unless you delve into bizarre syntaxis, where the lexical ordering matching processing ordering (if you want that, look at how reverse polish notation calculators work, or something like fortran - stack based language design. I don't think you'll like what you find there).一旦你看到这棵树,你就会看到优先级的概念是如何工作的——你的引擎需要能够同时表示(1 + 2) * 3以及1 + (2 * 3) ,所以没有树就这样做是不现实的除非你深入研究奇怪的语法,在那里词汇排序匹配处理排序(如果你想要,看看反向波兰符号计算器是如何工作的,或者像基于 fortran 堆栈的语言设计。我不认为你会喜欢什么你在那里找到)。

You're already making language design decisions here.您已经在这里做出语言设计决策。 Apparently, you think the language should adopt a 'truthy'/'falsy' concept, where dataMap.get("animal") which presumably returns an animal object, is to be considered as 'true' (as you're using it in a boolean operation) if, presumably, it isn't null or whatnot.显然,您认为该语言应该采用“真实”/“虚假”概念,其中可能返回动物对象的dataMap.get("animal")将被视为“真实”(因为您在一个布尔运算)如果,大概,它不为空或诸如此类。

So, you're designing an entire programming language here.因此,您在这里设计了一种完整的编程语言。 Why handicap yourself by enforcing that it is written in, of all things, JSON, which is epically unsuitable for the job?为什么要强制要求使用 JSON 来编写它,而这完全不适合这份工作呢? Go whole hog and write an entire language.全力以赴,编写一门完整的语言。 It'll take 2 to 3 years, of course.当然,这需要2到3年的时间。 Doing it in json isn't going to knock off more than a week off of that total, and make something that is so incredibly annoying to write, nobody would ever do it, buying you nothing.在 json 中做这件事不会让总数减少一个多星期,并且写出令人难以置信的烦人的东西,没有人会这样做,什么都不给你买。

The language will also naturally trend towards turing completeness.该语言也自然会趋向于图灵完整性。 Once a language is turing complete, it becomes mathematically impossible to answer such questions as: "Is this code ever going to actually finish running or will it loop forever?"一旦一种语言图灵完备,在数学上就不可能回答这样的问题:“这段代码会真正完成运行还是会永远循环下去?” (see 'halting problem'), you have no idea how much memory or CPU power it takes, and other issues that then result in security needs. (请参阅“停止问题”),您不知道它需要多少内存或 CPU 功率,以及导致安全需求的其他问题。 These are solvable problems (sandboxing, for example), but it's all very complicated.这些都是可以解决的问题(例如沙盒),但都非常复杂。

The JVM is, what, 2000 personyears worth of experience and effort? JVM 是什么,价值 2000 人年的经验和努力?

If you got 2000 years to write all this, by all means.如果你有 2000 年的时间来写这一切,无论如何。 The point is: There is no 'simple' way here.关键是:这里没有“简单”的方法。 It's a woefully incomplete thing that never feels like you can actually do what you'd want to do (which is express arbitrary ideas in a manner that feels natural enough, can be parsed by your system, and when you read back still makes sense), or it's as complex as any language would be.这是一件非常不完整的事情,永远不会觉得你真的可以做你想做的事(这是一种表达任意想法的方式,感觉足够自然,可以被你的系统解析,当你回读时仍然有意义) ,或者它和任何语言一样复杂。

Why not just ... use a language?为什么不只是......使用一种语言? Let folks write not JSON but write full blown java, or js, or python, or ruby, or lua, or anything else that already exists, is open source, seems well designed?让人们不写 JSON 而是写完整的 java、js、python、ruby、lua 或其他任何已经存在的东西,是开源的,看起来设计得很好吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM