Lex all XPath expressions in a single machine.

This allows literal values such as strings and numbers to be used as function
arguments.
This commit is contained in:
Yorick Peterse 2014-06-17 19:56:38 +02:00
parent a222bccd43
commit 894de7f909
2 changed files with 8 additions and 25 deletions

View File

@ -279,34 +279,16 @@ module Oga
| op_sub | op_sub
; ;
# Machine that handles the lexing of data inside an XPath predicate.
# When bumping into a "]" the lexer jumps back to the `main` machine.
predicate := |*
operator;
whitespace | slash | lparen | rparen | comma | colon | star;
string => emit_string;
integer => emit_integer;
float => emit_float;
axis_full => emit_axis_full;
axis_short => emit_axis_short;
identifier => emit_identifier;
']' => {
add_token(:T_RBRACK)
fnext main;
};
*|;
main := |* main := |*
operator; operator;
whitespace | slash | lparen | rparen | comma | colon | star; whitespace | slash | lparen | rparen | comma | colon | star;
'[' => { '[' => { add_token(:T_LBRACK) };
add_token(:T_LBRACK) ']' => { add_token(:T_RBRACK) };
fnext predicate;
};
string => emit_string;
integer => emit_integer;
float => emit_float;
axis_full => emit_axis_full; axis_full => emit_axis_full;
axis_short => emit_axis_short; axis_short => emit_axis_short;
identifier => emit_identifier; identifier => emit_identifier;

View File

@ -20,12 +20,13 @@ describe Oga::XPath::Lexer do
end end
example 'lex a function call with two arguments' do example 'lex a function call with two arguments' do
lex_xpath('count(foo, bar)').should == [ lex_xpath('count(/foo, "bar")').should == [
[:T_IDENT, 'count'], [:T_IDENT, 'count'],
[:T_LPAREN, nil], [:T_LPAREN, nil],
[:T_SLASH, nil],
[:T_IDENT, 'foo'], [:T_IDENT, 'foo'],
[:T_COMMA, nil], [:T_COMMA, nil],
[:T_IDENT, 'bar'], [:T_STRING, 'bar'],
[:T_RPAREN, nil] [:T_RPAREN, nil]
] ]
end end