From aeb4eba2608fced1de77341fa91b9f6524cadfba Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 10 Jul 2014 20:19:23 +0200 Subject: [PATCH] Trim the XPath AST. The AST has been simplified by adjusting the way (path) nodes are nested. Operators now also use `paths` instead of `expression` to allow for expressions such as `/A or /B`. Sadly this introduces quite a bunch of conflicts in the parser but we'll deal with those later if needed. --- lib/oga/xpath/parser.y | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/oga/xpath/parser.y b/lib/oga/xpath/parser.y index dd7c91c..b0f80aa 100644 --- a/lib/oga/xpath/parser.y +++ b/lib/oga/xpath/parser.y @@ -39,8 +39,12 @@ rule ; path - : expression { s(:path, val[0]) } - | expression T_SLASH path { s(:path, val[0], val[2]) } + : expressions { s(:path, *val[0]) } + ; + + expressions + : expression { val } + | expression T_SLASH expressions { [val[0], *val[2]] } ; expression @@ -70,20 +74,20 @@ rule ; operator - : expression T_PIPE expression { s(:pipe, val[0], val[2]) } - | expression T_AND expression { s(:and, val[0], val[2]) } - | expression T_OR expression { s(:or, val[0], val[2]) } - | expression T_ADD expression { s(:add, val[0], val[2]) } - | expression T_DIV expression { s(:div, val[0], val[2]) } - | expression T_MOD expression { s(:mod, val[0], val[2]) } - | expression T_EQ expression { s(:eq, val[0], val[2]) } - | expression T_NEQ expression { s(:neq, val[0], val[2]) } - | expression T_LT expression { s(:lt, val[0], val[2]) } - | expression T_GT expression { s(:gt, val[0], val[2]) } - | expression T_LTE expression { s(:lte, val[0], val[2]) } - | expression T_GTE expression { s(:gte, val[0], val[2]) } - | expression T_MUL expression { s(:mul, val[0], val[2]) } - | expression T_SUB expression { s(:sub, val[0], val[2]) } + : paths T_PIPE paths { s(:pipe, val[0], val[2]) } + | paths T_AND paths { s(:and, val[0], val[2]) } + | paths T_OR paths { s(:or, val[0], val[2]) } + | paths T_ADD paths { s(:add, val[0], val[2]) } + | paths T_DIV paths { s(:div, val[0], val[2]) } + | paths T_MOD paths { s(:mod, val[0], val[2]) } + | paths T_EQ paths { s(:eq, val[0], val[2]) } + | paths T_NEQ paths { s(:neq, val[0], val[2]) } + | paths T_LT paths { s(:lt, val[0], val[2]) } + | paths T_GT paths { s(:gt, val[0], val[2]) } + | paths T_LTE paths { s(:lte, val[0], val[2]) } + | paths T_GTE paths { s(:gte, val[0], val[2]) } + | paths T_MUL paths { s(:mul, val[0], val[2]) } + | paths T_SUB paths { s(:sub, val[0], val[2]) } ; axis