Skip to content

Commit

Permalink
fixed tag management
Browse files Browse the repository at this point in the history
  • Loading branch information
cadrian committed Apr 12, 2012
1 parent 8ae6bf1 commit f40ae41
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 18 deletions.
49 changes: 33 additions & 16 deletions src/lib/parse/grammar/packrat/packrat_grammar.e
Expand Up @@ -48,7 +48,7 @@ feature {}
reducer = a_reducer
end

the_table: PARSE_TABLE[PACKRAT_PARSE_CONTEXT] is
default_table: PARSE_TABLE[PACKRAT_PARSE_CONTEXT] is
once
Result := {PARSE_TABLE[PACKRAT_PARSE_CONTEXT] <<
-- ----------------------------------------------------------------------
Expand Down Expand Up @@ -158,11 +158,10 @@ feature {}
feature {ANY}
table: PARSE_TABLE[PACKRAT_PARSE_CONTEXT] is
do
Result := table_memory
if Result = Void then
Result := the_table
table_memory := Result
if table_memory = Void then
reset_table
end
Result := table_memory
end

reset is
Expand All @@ -171,6 +170,22 @@ feature {ANY}
reset_build_data
end

feature {EIFFELTEST_TOOLS} -- test only
set_table (a_table: like table; a_root: like root) is
do
table_memory := a_table
root := a_root
ensure
table = a_table
end

root: STRING

reset_table is
do
set_table(default_table, once "grammar")
end

feature {} -- low-level parsers
parse_string (buffer: MINI_PARSER_BUFFER; string: STRING): PACKRAT_IMAGE is
local
Expand Down Expand Up @@ -269,6 +284,7 @@ feature {} -- low-level parsers
string: STRING
do
if not buffer.end_reached then
string := once ""
string.clear_count
string.extend(buffer.current_character)
if regex.match(string) then
Expand Down Expand Up @@ -354,7 +370,7 @@ feature {} -- buffer moves
end

feature {ANY}
parse_table (a_source: ABSTRACT_STRING): like the_table is
parse_table (a_source: ABSTRACT_STRING): like default_table is
require
a_source /= Void
local
Expand All @@ -363,10 +379,14 @@ feature {ANY}
i: INTEGER
key: FIXED_STRING; item: PARSE_ATOM[PACKRAT_PARSE_CONTEXT]
do
if table_memory = Void then
reset_table
end

create parser
create buffer.initialize_with(a_source)

if parser.eval(buffer, table, once "grammar") then
if parser.eval(buffer, table, root) and then parser.error = Void then
create Result.with_capacity(last_atoms.count)
from
i := last_atoms.lower
Expand All @@ -378,9 +398,13 @@ feature {ANY}
Result.add(key, item)
i := i + 1
end
else
error := parser.error
end
end

error: PARSE_ERROR

feature {} -- build the grammar
reducer: PACKRAT_REDUCER

Expand Down Expand Up @@ -533,19 +557,12 @@ feature {} -- build the grammar
end

reduce_alternative_tag is
local
sequence: PACKRAT_SEQUENCE
do
check
last_lookahead = lookahead_none
end
if not last_tag.is_empty then
if sequence ?:= last_primary then
sequence ::= last_primary
sequence.set_tag(last_tag)
else
last_primary := seq(<< last_primary >>, one, last_tag, agent reducer.reduce_with_tag(last_nonterminal_def.intern, last_tag.intern))
end
last_primary := seq(<< last_primary >>, one, last_tag, agent reducer.reduce_with_tag(last_nonterminal_def.intern, last_tag.intern))
reset_tag
end
last_alternative.add_last(last_primary)
Expand Down Expand Up @@ -617,7 +634,7 @@ feature {} -- build the grammar
terminal_name := ("[#(1)]" # last_charclass).intern
terminal ::= atom(terminal_name)
if terminal = Void then
regex := regex_factory.convert_posix_pattern(last_charclass)
regex := regex_factory.convert_posix_pattern(terminal_name.out)
create terminal.make(agent parse_regex(?, regex), agent reduce_image_regex)
add_atom(terminal_name, terminal)
end
Expand Down
4 changes: 2 additions & 2 deletions test/lib/parse/test_packrat03.e
Expand Up @@ -23,10 +23,10 @@ feature {}

source := "[
grammar <- (nonterminal '<-' sp pattern {rule})+ {grammar}
pattern <- alternative ('/' sp alternative)*
pattern <- alternative {first_alternative} ('/' sp alternative {next_alternative})* {alternative}
alternative <- ([!&] sp suffix / suffix tag?)+
suffix <- primary ([*+?] sp)*
primary <- '(' sp pattern ')' sp / '.' sp / literal / charclass / nonterminal !'<-'
primary <- '(' sp pattern {nested} ')' sp / '.' sp / literal / charclass / nonterminal !'<-'
literal <- ['] (!['] .)* ['] sp
charclass <- '[' (!']' (. '-' . / .))* ']' sp
nonterminal <- [a-zA-Z]+ sp
Expand Down
83 changes: 83 additions & 0 deletions test/lib/parse/test_packrat04.e
@@ -0,0 +1,83 @@
class TEST_PACKRAT04

inherit
PACKRAT_REDUCER

insert
EIFFELTEST_TOOLS
LOGGING

create {}
make

feature {}
make is
local
grammar: PACKRAT_GRAMMAR
table: PARSE_TABLE[PACKRAT_PARSE_CONTEXT]
source: STRING; dump: STRING_OUTPUT_STREAM
parser: PACKRAT_PARSER; buffer: MINI_PARSER_BUFFER
do
create grammar.make(Current)

-- this one is the extended grammar (with tags),
-- decorated with tags

source := "[
grammar <- sp (nonterminal '<-' sp pattern {rule})+ {grammar}
pattern <- alternative {first_alternative} ('/' sp alternative {next_alternative})* {alternative}
alternative <- ([!&] sp suffix / suffix tag?)+
suffix <- primary ([*+?] sp)*
primary <- '(' sp pattern {nested} ')' sp / '.' sp / literal / charclass / nonterminal !'<-'
literal <- ['] (!['] .)* ['] sp
charclass <- '[' (!']' (. '-' . / .))* ']' sp
nonterminal <- [a-zA-Z]+ sp
sp <- [ \t\n]*
tag <- '{' (!'}' .)+ '}' sp
]"

table := grammar.parse_table(source)
assert(table /= Void)
table.pretty_print_on(log.info)
create dump.make
table.pretty_print_on(dump)
assert(source.is_equal(dump.to_string))

create parser
create buffer.initialize_with(source)
assert(parser.eval(buffer, table, "grammar") and then parser.error = Void)
end

feature {PACKRAT_GRAMMAR}
reduce_alternative (nonterminal_name: FIXED_STRING) is
do
log.trace.put_line("#### reduce alternative: nonterminal %"#(1)%"" # nonterminal_name)
end

reduce_pattern (nonterminal_name: FIXED_STRING) is
do
log.trace.put_line("#### reduce pattern: nonterminal %"#(1)%"" # nonterminal_name)
end

reduce_positive_lookahead (nonterminal_name: FIXED_STRING) is
do
log.trace.put_line("#### reduce positive lookahead: nonterminal %"#(1)%"" # nonterminal_name)
end

reduce_negative_lookahead (nonterminal_name: FIXED_STRING) is
do
log.trace.put_line("#### reduce negative lookahead: nonterminal %"#(1)%"" # nonterminal_name)
end

reduce_loop (nonterminal_name: FIXED_STRING; quantifier: INTEGER_8) is
do
log.trace.put_line("#### reduce loop: nonterminal %"#(1)%", #(2)" # nonterminal_name # quantifier.out)
end

reduce_with_tag (nonterminal_name, tag: FIXED_STRING) is
do
log.trace.put_line("#### reduce tag: nonterminal %"#(1)%", tag {#(2)}" # nonterminal_name # tag)
end

end

0 comments on commit f40ae41

Please sign in to comment.