180 lines
4.4 KiB
Ragel
180 lines
4.4 KiB
Ragel
%%{
|
|
machine parser;
|
|
|
|
action _prefix { mark_pfx = p; }
|
|
action prefix {
|
|
prefix = input.substring(mark_pfx, p);
|
|
}
|
|
action _check_prefix {
|
|
if ( !prefix.equals(tag_prefix) ) {
|
|
// have to manually add ':' / Sep
|
|
// pass the text through & reset state
|
|
pass_through(input.substring(tagstart, p) + ":");
|
|
prefix = "";
|
|
fgoto main;
|
|
}
|
|
}
|
|
|
|
action _starttag { mark_stg = p; }
|
|
action starttag { name = input.substring(mark_stg, p); }
|
|
action _attr { mark_attr = p; }
|
|
action attr {
|
|
attributes.op_aset(
|
|
runtime.getCurrentContext(),
|
|
RubyString.newString(runtime, nat),
|
|
RubyString.newString(runtime, vat)
|
|
);
|
|
}
|
|
|
|
action _nameattr { mark_nat = p; }
|
|
action nameattr { nat = input.substring(mark_nat, p); }
|
|
action _valattr { mark_vat = p; }
|
|
action valattr { vat = input.substring(mark_vat, p); }
|
|
|
|
action opentag { flavor = RubySymbol.newSymbol(runtime, "open".intern()); }
|
|
action selftag { flavor = RubySymbol.newSymbol(runtime, "self".intern()); }
|
|
action closetag { flavor = RubySymbol.newSymbol(runtime, "close".intern()); }
|
|
|
|
Closeout := empty;
|
|
|
|
# words
|
|
PrefixChar = [\-A-Za-z0-9._?] ;
|
|
NameChar = [\-A-Za-z0-9._:?] ;
|
|
TagName = NameChar+ >_starttag %starttag;
|
|
Prefix = PrefixChar+ >_prefix %prefix;
|
|
Open = "<";
|
|
Sep = ":" >_check_prefix;
|
|
End = "/";
|
|
Close = ">";
|
|
|
|
Name = Prefix Sep TagName;
|
|
|
|
NameAttr = NameChar+ >_nameattr %nameattr;
|
|
Q1Char = ( "\\\'" | [^'] ) ;
|
|
Q1Attr = Q1Char* >_valattr %valattr;
|
|
Q2Char = ( "\\\"" | [^"] ) ;
|
|
Q2Attr = Q2Char* >_valattr %valattr;
|
|
|
|
Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr;
|
|
Attrs = (space+ Attr* | empty);
|
|
|
|
CloseTrailer = End Close %selftag;
|
|
OpenTrailer = Close %opentag;
|
|
|
|
Trailer = (OpenTrailer | CloseTrailer);
|
|
|
|
OpenOrSelfTag = Name Attrs? Trailer;
|
|
CloseTag = End Name space* Close %closetag;
|
|
|
|
SomeTag = Open (OpenOrSelfTag | CloseTag);
|
|
|
|
main := |*
|
|
SomeTag => {
|
|
tag(prefix, name, attributes, flavor);
|
|
prefix = "";
|
|
name = "";
|
|
attributes = RubyHash.newHash(runtime);
|
|
flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
|
|
};
|
|
any => {
|
|
pass_through(input.substring(p, p + 1));
|
|
tagstart = p + 1;
|
|
};
|
|
*|;
|
|
}%%
|
|
|
|
package radius.parser;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import org.jruby.Ruby; // runtime
|
|
import org.jruby.RubyObject;
|
|
import org.jruby.runtime.builtin.IRubyObject;
|
|
import org.jruby.RubyArray;
|
|
import org.jruby.RubyString;
|
|
import org.jruby.RubyHash;
|
|
import org.jruby.RubySymbol;
|
|
|
|
public class JavaScanner {
|
|
|
|
Ruby runtime = null;
|
|
RubyArray rv = null;
|
|
|
|
void pass_through(String str) {
|
|
RubyObject last = ((RubyObject)rv.last());
|
|
if ( rv.size() > 0 && last != null && (last instanceof RubyString) ){
|
|
// XXX concat changes for ruby 1.9
|
|
((RubyString) last).concat(RubyString.newString(runtime, str));
|
|
} else {
|
|
rv.append(RubyString.newString(runtime, str));
|
|
}
|
|
}
|
|
|
|
void tag(String prefix, String name, RubyHash attr, RubySymbol flavor) {
|
|
RubyHash tag = RubyHash.newHash(runtime);
|
|
tag.op_aset(
|
|
runtime.getCurrentContext(),
|
|
RubySymbol.newSymbol(runtime, "prefix"),
|
|
RubyString.newString(runtime, prefix)
|
|
);
|
|
tag.op_aset(
|
|
runtime.getCurrentContext(),
|
|
RubySymbol.newSymbol(runtime, "name"),
|
|
RubyString.newString(runtime, name)
|
|
);
|
|
tag.op_aset(
|
|
runtime.getCurrentContext(),
|
|
RubySymbol.newSymbol(runtime, "attrs"),
|
|
attr
|
|
);
|
|
tag.op_aset(
|
|
runtime.getCurrentContext(),
|
|
RubySymbol.newSymbol(runtime, "flavor"),
|
|
flavor
|
|
);
|
|
rv.append(tag);
|
|
}
|
|
|
|
public JavaScanner(Ruby runtime) {
|
|
this.runtime = runtime;
|
|
}
|
|
|
|
%% write data;
|
|
|
|
public RubyArray operate(String tag_prefix, String input) {
|
|
char[] data = input.toCharArray();
|
|
String disposable_string;
|
|
|
|
String name = "";
|
|
String prefix = "";
|
|
RubySymbol flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
|
|
RubyHash attributes = RubyHash.newHash(runtime);
|
|
|
|
int tagstart = 0;
|
|
int mark_pfx = 0;
|
|
int mark_stg = 0;
|
|
int mark_attr = 0;
|
|
int mark_nat = 0;
|
|
int mark_vat = 0;
|
|
|
|
String nat = "";
|
|
String vat = "";
|
|
|
|
int cs;
|
|
int p = 0;
|
|
int pe = data.length;
|
|
int eof = pe;
|
|
int act;
|
|
int ts;
|
|
int te;
|
|
|
|
rv = RubyArray.newArray(runtime);
|
|
char[] remainder = data;
|
|
|
|
%% write init;
|
|
%% write exec;
|
|
|
|
return rv;
|
|
}
|
|
}
|