Проанализируйте выражения XPath

Ух ты, похоже, ты в замешательстве. Это понятно, так как слово «карта» означает как минимум четыре разные вещи!

  1. Модуль Data.Map (вам, кажется, ясно об этом)
  2. Данные тип Map.Map k v (в модуле Data.Map), который является конечным отображением, он же «словарь», он же «хеш-таблица» (но не использует хеширование)
  3. The [1131 ] функция Map.map (в модуле Data.Map), которая применяет функцию к каждому значению в Map (словарь)
  4. Существует также стандартная функция map (в [ 1111]), который работает со списками и не имеет ничего общего с Map s (словарями).

Вот так, что за глоток!


Вот некоторые объяснения сигнатур:

Map.fromList :: (Ord k) => [(k, a)] -> Map.Map k a

Map.Map k a - параметризованный тип данных с двумя параметрами, [ 1114] и a. Если вы знакомы с дженериками в семействе C ++, это может быть написано Map<K, A>.

Функция fromList принимает список пар (ключ, значение), [(k, a)] и возвращает словарь. Ключи словаря имеют тип k, а значения имеют тип a. (Ord k) означает, что ключи должны быть упорядочены по отношению друг к другу, поскольку они хранят структуру данных в виде отсортированного сбалансированного дерева.

-- A dictionary from people's names to their age
ages :: Map.Map String Int
ages = Map.fromList [("Bill", 32), ("Carol", 71), ("Diddy", 13)]

Map.map :: (a -> b) -> Map.Map k a -> Map.Map k b

Это принимает функцию от вещей типа a к вещам типа b в качестве первого параметра. В качестве второго параметра он принимает словарь из любого типа ключа k для вещей типа a и применяет функцию к каждому значению в словаре, возвращая словарь из того же типа ключа для вещей типа b ].

-- A dictionary from people's names to whether they are allowed to drink alcohol
canDrink :: Map.Map String Bool
canDrink = Map.map (\age -> age >= 21) ages

fromList' - это просто пользовательская реализация fromList, реализованная путем многократной вставки. Неудивительно, что он имеет ту же сигнатуру, что и fromList (но переменные типа называются по-разному - это не имеет значения).

6
задан Jonathan C Dickinson 6 February 2009 в 08:56
поделиться

1 ответ

Существует antlr xpath грамматика здесь. Начиная с его разрешений на лицензию я скопировал целую грамматику здесь для предотвращения гнили ссылки в будущем.

grammar xpath;

/*
XPath 1.0 grammar. Should conform to the official spec at
http://www.w3.org/TR/1999/REC-xpath-19991116. The grammar
rules have been kept as close as possible to those in the
spec, but some adjustmewnts were unavoidable. These were
mainly removing left recursion (spec seems to be based on
LR), and to deal with the double nature of the '*' token
(node wildcard and multiplication operator). See also
section 3.7 in the spec. These rule changes should make
no difference to the strings accepted by the grammar.
Written by Jan-Willem van den Broek
Version 1.0
Do with this code as you will.
*/
/*
    Ported to Antlr4 by Tom Everett <tom@khubla.com>
*/


main  :  expr
  ;

locationPath 
  :  relativeLocationPath
  |  absoluteLocationPathNoroot
  ;

absoluteLocationPathNoroot
  :  '/' relativeLocationPath
  |  '//' relativeLocationPath
  ;

relativeLocationPath
  :  step (('/'|'//') step)*
  ;

step  :  axisSpecifier nodeTest predicate*
  |  abbreviatedStep
  ;

axisSpecifier
  :  AxisName '::'
  |  '@'?
  ;

nodeTest:  nameTest
  |  NodeType '(' ')'
  |  'processing-instruction' '(' Literal ')'
  ;

predicate
  :  '[' expr ']'
  ;

abbreviatedStep
  :  '.'
  |  '..'
  ;

expr  :  orExpr
  ;

primaryExpr
  :  variableReference
  |  '(' expr ')'
  |  Literal
  |  Number  
  |  functionCall
  ;

functionCall
  :  functionName '(' ( expr ( ',' expr )* )? ')'
  ;

unionExprNoRoot
  :  pathExprNoRoot ('|' unionExprNoRoot)?
  |  '/' '|' unionExprNoRoot
  ;

pathExprNoRoot
  :  locationPath
  |  filterExpr (('/'|'//') relativeLocationPath)?
  ;

filterExpr
  :  primaryExpr predicate*
  ;

orExpr  :  andExpr ('or' andExpr)*
  ;

andExpr  :  equalityExpr ('and' equalityExpr)*
  ;

equalityExpr
  :  relationalExpr (('='|'!=') relationalExpr)*
  ;

relationalExpr
  :  additiveExpr (('<'|'>'|'<='|'>=') additiveExpr)*
  ;

additiveExpr
  :  multiplicativeExpr (('+'|'-') multiplicativeExpr)*
  ;

multiplicativeExpr
  :  unaryExprNoRoot (('*'|'div'|'mod') multiplicativeExpr)?
  |  '/' (('div'|'mod') multiplicativeExpr)?
  ;

unaryExprNoRoot
  :  '-'* unionExprNoRoot
  ;

qName  :  nCName (':' nCName)?
  ;

functionName
  :  qName  // Does not match nodeType, as per spec.
  ;

variableReference
  :  '$' qName
  ;

nameTest:  '*'
  |  nCName ':' '*'
  |  qName
  ;

nCName  :  NCName
  |  AxisName
  ;

NodeType:  'comment'
  |  'text'
  |  'processing-instruction'
  |  'node'
  ;

Number  :  Digits ('.' Digits?)?
  |  '.' Digits
  ;

fragment
Digits  :  ('0'..'9')+
  ;

AxisName:  'ancestor'
  |  'ancestor-or-self'
  |  'attribute'
  |  'child'
  |  'descendant'
  |  'descendant-or-self'
  |  'following'
  |  'following-sibling'
  |  'namespace'
  |  'parent'
  |  'preceding'
  |  'preceding-sibling'
  |  'self'
  ;


  PATHSEP 
       :'/';
  ABRPATH   
       : '//';
  LPAR   
       : '(';
  RPAR   
       : ')';
  LBRAC   
       :  '[';
  RBRAC   
       :  ']';
  MINUS   
       :  '-';
  PLUS   
       :  '+';
  DOT   
       :  '.';
  MUL   
       : '*';
  DOTDOT   
       :  '..';
  AT   
       : '@';
  COMMA  
       : ',';
  PIPE   
       :  '|';
  LESS   
       :  '<';
  MORE_ 
       :  '>';
  LE   
       :  '<=';
  GE   
       :  '>=';
  COLON   
       :  ':';
  CC   
       :  '::';
  APOS   
       :  '\'';
  QUOT   
       :  '\"';

Literal  :  '"' ~'"'* '"'
  |  '\'' ~'\''* '\''
  ;

Whitespace
  :  (' '|'\t'|'\n'|'\r')+ ->skip
  ;

NCName  :  NCNameStartChar NCNameChar*
  ;

fragment
NCNameStartChar
  :  'A'..'Z'
  |   '_'
  |  'a'..'z'
  |  '\u00C0'..'\u00D6'
  |  '\u00D8'..'\u00F6'
  |  '\u00F8'..'\u02FF'
  |  '\u0370'..'\u037D'
  |  '\u037F'..'\u1FFF'
  |  '\u200C'..'\u200D'
  |  '\u2070'..'\u218F'
  |  '\u2C00'..'\u2FEF'
  |  '\u3001'..'\uD7FF'
  |  '\uF900'..'\uFDCF'
  |  '\uFDF0'..'\uFFFD'
// Unfortunately, java escapes can't handle this conveniently,
// as they're limited to 4 hex digits. TODO.
//  |  '\U010000'..'\U0EFFFF'
  ;

fragment
NCNameChar
  :  NCNameStartChar | '-' | '.' | '0'..'9'
  |  '\u00B7' | '\u0300'..'\u036F'
  |  '\u203F'..'\u2040'
  ;
2
ответ дан 17 December 2019 в 07:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: