1

尝试构建一个可以解析简单布尔表达式的语法。
当有多个表达式时,我遇到了一个问题。
我需要能够解析1..n and/or'ed 表达式。

下面的每个示例都是一个完整的表达式:

  1. (myitem.isavailable("1234") or myitem.ispresent("1234")) and myitem.isready("1234")
  2. myitem.value > 4 and myitem.value < 10
  3. myitem.value = yes or myotheritem.value = no

语法:

@start = conditionalexpression* | expressiontypes;

conditionalexpression = condition expressiontypes;

expressiontypes = expression | functionexpression;

expression = itemname dot property condition value;

functionexpression = itemname dot functionproperty;

itemname = Word;

propertytypes = property | functionproperty;

property = Word;

functionproperty =  Word '(' value ')';

value = Word | QuotedString | Number;

condition = textcondition;

dot = '.';

textcondition = 'or' | 'and' | '<' | '>' | '=';
4

1 回答 1

1

ParseKit的开发者在这里。

这是与您的示例输入匹配的 ParseKit 语法:

@start = expr;

expr = orExpr;

orExpr = andExpr orTerm*;
orTerm = 'or' andExpr;

  // 'and' should bind more tightly than 'or'
andExpr = relExpr andTerm*;
andTerm = 'and' relExpr;

  // relational expressions should bind more tightly than 'and'/'or'
relExpr = callExpr relTerm*;
relTerm = relOp callExpr;

  // func calls should bind more tightly than relational expressions
callExpr = primaryExpr ('(' argList ')')?;
argList = Empty | atom (',' atom)*;

primaryExpr     = atom | '(' expr ')';
atom            = obj | literal;

  // member access should bind most tightly
obj     = id member*;
member  = ('.' id);

id      = Word;
literal = Number | QuotedString | bool;
bool    = 'yes' | 'no';

relOp   = '<' | '>' | '=';

为了让您了解我是如何得出这个语法的:

  1. 我意识到你的语言是一种简单的、可组合的表达语言。
  2. 我记得 XPath 1.0 也是一种相对简单的表达式语言,具有易于使用/可读的语法。
  3. 在线访问了 XPath 1.0 规范并快速浏览了 XPath 基本语言语法。这为设计你的语言语法提供了一个快速的起点。如果忽略 XPath 表达式的路径表达式部分,XPath 是一个非常好的基本表达式语言模板。

我上面的语法成功地解析了你所有的示例输入(见下文)。希望这可以帮助。

[foo, ., bar, (, "hello", ), or, (, bar, or, baz, >, bat, )]foo/./bar/(/"hello"/)/or/(/bar/or/baz/>/bat/)^
[myitem, ., value, >, 4, and, myitem, ., value, <, 10]myitem/./value/>/4/and/myitem/./value/</10^
[myitem, ., value, =, yes, or, myotheritem, ., value, =, no]myitem/./value/=/yes/or/myotheritem/./value/=/no^
于 2013-03-20T19:08:54.167 回答