diff --git a/中文.erl b/中文.erl deleted file mode 100644 index ab56b9c..0000000 --- a/中文.erl +++ /dev/null @@ -1,518 +0,0 @@ --module(protoParse). - --export([ - parseParse/1 - , parseFile/1 -]). - --define(p_anything, true). --define(p_charclass, true). --define(p_choose, true). --define(p_label, true). --define(p_not, true). --define(p_one_or_more, true). --define(p_optional, true). --define(p_scan, true). --define(p_seq, true). --define(p_string, true). --define(p_zero_or_more, true). - - - --spec parseFile(file:name()) -> any(). -parseFile(Filename) -> - case file:read_file(Filename) of - {ok, Bin} -> - parseParse(Bin); - Err -> Err - end. - --spec parseParse(binary() | list()) -> any(). -parseParse(List) when is_list(List) -> - parseParse(unicode:characters_to_binary(List)); -parseParse(Input) when is_binary(Input) -> - setup_memo(), - Result = case 'all'(Input, {{line, 1}, {column, 1}}) of - {AST, <<>>, _Index} -> - AST; - Any -> - Any - end, - release_memo(), - Result. - --spec 'all'(input(), index()) -> parse_result(). -'all'(Input, Index) -> - p(Input, Index, 'all', fun(I, D) -> - (p_seq([fun 'blank0'/2, p_zero_or_more(p_seq([p_choose([fun 'type'/2, fun 'protocol'/2]), fun 'blank0'/2]))]))(I, D) end, fun(Node, _Idx) -> - [_ | [T]] = Node, - DataList = [H || [H | _] <- T], - - DataList - end). - --spec 'protocol'(input(), index()) -> parse_result(). -'protocol'(Input, Index) -> - p(Input, Index, 'protocol', fun(I, D) -> - (p_seq([p_label('name', fun 'name'/2), fun 'blanks'/2, p_label('tag', fun 'tag'/2), fun 'blank0'/2, p_string(<<"{">>), fun 'blank0'/2, p_label('sub', p_zero_or_more(p_seq([fun 'subproto'/2, fun 'blank0'/2]))), p_string(<<"}">>)]))(I, D) end, fun(Node, _Idx) -> - Name = binary_to_list(iolist_to_binary(proplists:get_value(name, Node))), - Tag = list_to_integer(binary_to_list(iolist_to_binary(proplists:get_value(tag, Node)))), - SubList = proplists:get_value(sub, Node), - SubProtoList = [Head || [Head, _] <- SubList], - {protocol, Name, Tag, SubProtoList} - end). - --spec 'subproto'(input(), index()) -> parse_result(). -'subproto'(Input, Index) -> - p(Input, Index, 'subproto', fun(I, D) -> - (p_seq([p_label('parta', p_choose([p_string(<<"request">>), p_string(<<"response">>)])), fun 'blanks'/2, p_label('partb', p_choose([fun 'typename'/2, fun 'struct'/2]))]))(I, D) end, fun(Node, _Idx) -> - Parta = binary_to_list(iolist_to_binary(proplists:get_value(parta, Node))), - Partb = proplists:get_value(partb, Node), - Partb2 = - case is_tuple(Partb) of - false -> Partb; - true -> element(1, Partb) - end, - {Parta, Partb2} - end). - --spec 'type'(input(), index()) -> parse_result(). -'type'(Input, Index) -> - p(Input, Index, 'type', fun(I, D) -> - (p_seq([p_string(<<".">>), p_label('name', fun 'name'/2), fun 'blank0'/2, p_label('struct', fun 'struct'/2)]))(I, D) end, fun(Node, _Idx) -> - Name = binary_to_list(iolist_to_binary(proplists:get_value(name, Node))), - Struct = proplists:get_value(struct, Node), - Tag = get(messageid), - put(messageid, Tag + 1), - {Name, Tag, Struct} - end). - --spec 'struct'(input(), index()) -> parse_result(). -'struct'(Input, Index) -> - p(Input, Index, 'struct', fun(I, D) -> - (p_seq([p_string(<<"{">>), fun 'blank0'/2, p_zero_or_more(p_seq([p_choose([fun 'field'/2, fun 'type'/2]), fun 'blank0'/2])), p_string(<<"}">>)]))(I, D) end, fun(Node, _Idx) -> - [_, _, List, _] = Node, - [H || [H | _] <- List] - end). - --spec 'field'(input(), index()) -> parse_result(). -'field'(Input, Index) -> - p(Input, Index, 'field', fun(I, D) -> - (p_seq([p_label('name', fun 'name'/2), fun 'blanks'/2, p_string(<<":">>), fun 'blank0'/2, p_label('isarray', p_zero_or_more(p_string(<<"*">>))), p_label('datatype', fun 'typename'/2), p_label('key', p_zero_or_more(fun 'mainkey'/2))]))(I, D) end, fun(Node, _Idx) -> - Name = binary_to_list(iolist_to_binary(proplists:get_value(name, Node))), - IsArray = - case proplists:get_value(isarray, Node) =:= [<<"*">>] of - true -> - true; - false -> - false - end, - {FieldType, DataType} = - case proplists:get_value(datatype, Node) of - {"boolean", _} -> - case IsArray of - true -> - {4, 1}; - _ -> - {1, 1} - end; - {"integer", _} -> - case IsArray of - true -> - {4, 2}; - _ -> - {2, 2} - end; - {"string", _} -> - case IsArray of - true -> - {4, 3}; - _ -> - {3, 3} - end; - {Other, SubName} -> - case IsArray of - true -> - {4, Other ++ SubName}; - _ -> - {5, Other ++ SubName} - end - end, - {Name, FieldType, DataType} - end). - --spec 'eof'(input(), index()) -> parse_result(). -'eof'(Input, Index) -> - p(Input, Index, 'eof', fun(I, D) -> (p_not(p_string(<<".">>)))(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'newline'(input(), index()) -> parse_result(). -'newline'(Input, Index) -> - p(Input, Index, 'newline', fun(I, D) -> - (p_seq([p_optional(p_charclass(<<"[\r]">>)), p_charclass(<<"[\n]">>)]))(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'line_comment'(input(), index()) -> parse_result(). -'line_comment'(Input, Index) -> - p(Input, Index, 'line_comment', - fun(I, D) -> - (p_seq([p_string(<<"#">>), p_label('errorcode', p_zero_or_more(p_seq([p_string(<<"$errcode">>), fun 'blanks'/2, fun 'name'/2, fun 'blanks'/2, fun 'words'/2]))), p_zero_or_more(p_seq([p_not(fun 'newline'/2), p_anything()])), p_choose([fun 'newline'/2, fun 'eof'/2])]))(I, D) - end, - fun(Node, _Idx) -> - case proplists:get_value(errorcode, Node) of - [[_ErrorCode, _Space, Tail, _Space1, Comment]] -> - ErrName = binary_to_list(iolist_to_binary(Tail)), - ComDesc = (iolist_to_binary(Comment)), - ErrNameList = erlang:get(errorname), - case ErrName =/= [] andalso lists:keyfind(ErrName, 1, ErrNameList) == false of - true -> - ErrCode = erlang:get(errorid), - erlang:put(errorname, [{ErrName, ErrCode, ComDesc} | ErrNameList]), - erlang:put(errorid, ErrCode + 1); - _ -> - skip - end; - _AAa -> - skip - end, - Node - end). - --spec 'blank'(input(), index()) -> parse_result(). -'blank'(Input, Index) -> - p(Input, Index, 'blank', fun(I, D) -> - (p_choose([p_charclass(<<"[\s\t]">>), fun 'newline'/2, fun 'errorcode'/2, fun 'line_comment'/2]))(I, D) end, fun(Node, _Idx) -> - Node end). - --spec 'blank0'(input(), index()) -> parse_result(). -'blank0'(Input, Index) -> - p(Input, Index, 'blank0', fun(I, D) -> (p_zero_or_more(fun 'blank'/2))(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'blanks'(input(), index()) -> parse_result(). -'blanks'(Input, Index) -> - p(Input, Index, 'blanks', fun(I, D) -> (p_one_or_more(fun 'blank'/2))(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'alpha'(input(), index()) -> parse_result(). -'alpha'(Input, Index) -> - p(Input, Index, 'alpha', fun(I, D) -> - (p_choose([p_charclass(<<"[a-z]">>), p_charclass(<<"[A-Z]">>), p_string(<<"_">>)]))(I, D) end, fun(Node, _Idx) -> - Node end). - --spec 'str'(input(), index()) -> parse_result(). -'str'(Input, Index) -> - p(Input, Index, 'str', - fun(I, D) -> - (p_seq([p_not(fun 'newline'/2), p_charclass(<<".">>)]))(I, D) - end, - fun(Node, _Idx) -> - Node - end). - --spec 'alnum'(input(), index()) -> parse_result(). -'alnum'(Input, Index) -> - p(Input, Index, 'alnum', fun(I, D) -> - (p_choose([fun 'alpha'/2, p_charclass(<<"[0-9]">>)]))(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'word'(input(), index()) -> parse_result(). -'word'(Input, Index) -> - p(Input, Index, 'word', fun(I, D) -> - (p_seq([fun 'alpha'/2, p_zero_or_more(fun 'alnum'/2)]))(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'words'(input(), index()) -> parse_result(). -'words'(Input, Index) -> - p(Input, Index, 'words', fun(I, D) -> - (p_seq([p_choose([p_zero_or_more(fun 'str'/2), p_zero_or_more(fun 'word'/2)])]))(I, D) end, fun(Node, _Idx) -> - Node end). - --spec 'name'(input(), index()) -> parse_result(). -'name'(Input, Index) -> - p(Input, Index, 'name', fun(I, D) -> (fun 'word'/2)(I, D) end, fun(Node, _Idx) -> Node end). - --spec 'typename'(input(), index()) -> parse_result(). -'typename'(Input, Index) -> - p(Input, Index, 'typename', fun(I, D) -> - (p_seq([fun 'word'/2, p_zero_or_more(p_seq([p_string(<<".">>), fun 'word'/2]))]))(I, D) end, fun(Node, _Idx) -> - [Head, List] = Node, - SubName = - case List of - [] -> ""; - _ -> - List2 = [[Dot, iolist_to_binary(Word)] || [Dot, Word] <- List], - binary_to_list(list_to_binary(lists:append(List2))) - end, - {binary_to_list(iolist_to_binary(Head)), SubName} - end). - --spec 'tag'(input(), index()) -> parse_result(). -'tag'(Input, Index) -> - p(Input, Index, 'tag', fun(I, D) -> (p_one_or_more(p_charclass(<<"[0-9]">>)))(I, D) end, fun(Node, _Idx) -> - Node end). - --spec 'mainkey'(input(), index()) -> parse_result(). -'mainkey'(Input, Index) -> - p(Input, Index, 'mainkey', fun(I, D) -> - (p_seq([p_string(<<"(">>), fun 'blank0'/2, p_label('name', fun 'name'/2), fun 'blank0'/2, p_string(<<")">>)]))(I, D) end, fun(Node, _Idx) -> - proplists:get_value(name, Node) - end). - - - --file("peg_includes.hrl", 1). --type index() :: {{line, pos_integer()}, {column, pos_integer()}}. --type input() :: binary(). --type parse_failure() :: {fail, term()}. --type parse_success() :: {term(), input(), index()}. --type parse_result() :: parse_failure() | parse_success(). --type parse_fun() :: fun((input(), index()) -> parse_result()). --type xform_fun() :: fun((input(), index()) -> term()). - --spec p(input(), index(), atom(), parse_fun(), xform_fun()) -> parse_result(). -p(Inp, StartIndex, Name, ParseFun, TransformFun) -> - case get_memo(StartIndex, Name) of % See if the current reduction is memoized - {ok, Memo} -> % If it is, return the stored result - Memo; - _ -> % If not, attempt to parse - Result = case ParseFun(Inp, StartIndex) of - {fail, _} = Failure -> % If it fails, memoize the failure - Failure; - {Match, InpRem, NewIndex} -> % If it passes, transform and memoize the result. - Transformed = TransformFun(Match, StartIndex), - {Transformed, InpRem, NewIndex} - end, - memoize(StartIndex, Name, Result), - Result - end. - --spec setup_memo() -> ets:tid(). -setup_memo() -> - put({parse_memo_table, ?MODULE}, - ets:new(?MODULE, [set])). - --spec release_memo() -> true. -release_memo() -> - ets:delete(memo_table_name()). - --spec memoize(index(), atom(), parse_result()) -> true. -memoize(Index, Name, Result) -> - Memo = case ets:lookup(memo_table_name(), Index) of - [] -> - []; - [{Index, Plist}] -> - Plist - end, - ets:insert(memo_table_name(), {Index, [{Name, Result} | Memo]}). - --spec get_memo(index(), atom()) -> {ok, term()} | {error, not_found}. -get_memo(Index, Name) -> - case ets:lookup(memo_table_name(), Index) of - [] -> - {error, not_found}; - [{Index, Plist}] -> - case proplists:lookup(Name, Plist) of - {Name, Result} -> - {ok, Result}; - _ -> - {error, not_found} - end - end. - --spec memo_table_name() -> ets:tid(). -memo_table_name() -> - get({parse_memo_table, ?MODULE}). - --ifdef(p_eof). --spec p_eof() -> parse_fun(). -p_eof() -> - fun(<<>>, Index) -> {eof, [], Index}; - (_, Index) -> {fail, {expected, eof, Index}} end. --endif. - --ifdef(p_optional). --spec p_optional(parse_fun()) -> parse_fun(). -p_optional(P) -> - fun(Input, Index) -> - case P(Input, Index) of - {fail, _} -> - {[], Input, Index}; - {_, _, _} = Success -> - Success - end - end. --endif. - --ifdef(p_not). --spec p_not(parse_fun()) -> parse_fun(). -p_not(P) -> - fun(Input, Index) -> - case P(Input, Index) of - {fail, _} -> - {[], Input, Index}; - {Result, _, _} -> {fail, {expected, {no_match, Result}, Index}} - end - end. --endif. - --ifdef(p_assert). --spec p_assert(parse_fun()) -> parse_fun(). -p_assert(P) -> - fun(Input, Index) -> - case P(Input, Index) of - {fail, _} = Failure -> Failure; - _ -> {[], Input, Index} - end - end. --endif. - --ifdef(p_seq). --spec p_seq([parse_fun()]) -> parse_fun(). -p_seq(P) -> - fun(Input, Index) -> - p_all(P, Input, Index, []) - end. - --spec p_all([parse_fun()], input(), index(), [term()]) -> parse_result(). -p_all([], Inp, Index, Accum) -> {lists:reverse(Accum), Inp, Index}; -p_all([P | Parsers], Inp, Index, Accum) -> - case P(Inp, Index) of - {fail, _} = Failure -> Failure; - {Result, InpRem, NewIndex} -> p_all(Parsers, InpRem, NewIndex, [Result | Accum]) - end. --endif. - --ifdef(p_choose). --spec p_choose([parse_fun()]) -> parse_fun(). -p_choose(Parsers) -> - fun(Input, Index) -> - p_attempt(Parsers, Input, Index, none) - end. - --spec p_attempt([parse_fun()], input(), index(), none | parse_failure()) -> parse_result(). -p_attempt([], _Input, _Index, Failure) -> Failure; -p_attempt([P | Parsers], Input, Index, FirstFailure) -> - case P(Input, Index) of - {fail, _} = Failure -> - case FirstFailure of - none -> p_attempt(Parsers, Input, Index, Failure); - _ -> p_attempt(Parsers, Input, Index, FirstFailure) - end; - Result -> Result - end. --endif. - --ifdef(p_zero_or_more). --spec p_zero_or_more(parse_fun()) -> parse_fun(). -p_zero_or_more(P) -> - fun(Input, Index) -> - p_scan(P, Input, Index, []) - end. --endif. - --ifdef(p_one_or_more). --spec p_one_or_more(parse_fun()) -> parse_fun(). -p_one_or_more(P) -> - fun(Input, Index) -> - Result = p_scan(P, Input, Index, []), - case Result of - {[_ | _], _, _} -> - Result; - _ -> - {fail, {expected, Failure, _}} = P(Input, Index), - {fail, {expected, {at_least_one, Failure}, Index}} - end - end. --endif. - --ifdef(p_label). --spec p_label(atom(), parse_fun()) -> parse_fun(). -p_label(Tag, P) -> - fun(Input, Index) -> - case P(Input, Index) of - {fail, _} = Failure -> - Failure; - {Result, InpRem, NewIndex} -> - {{Tag, Result}, InpRem, NewIndex} - end - end. --endif. - --ifdef(p_scan). --spec p_scan(parse_fun(), input(), index(), [term()]) -> {[term()], input(), index()}. -p_scan(_, <<>>, Index, Accum) -> {lists:reverse(Accum), <<>>, Index}; -p_scan(P, Inp, Index, Accum) -> - case P(Inp, Index) of - {fail, _} -> {lists:reverse(Accum), Inp, Index}; - {Result, InpRem, NewIndex} -> p_scan(P, InpRem, NewIndex, [Result | Accum]) - end. --endif. - --ifdef(p_string). --spec p_string(binary()) -> parse_fun(). -p_string(S) -> - Length = erlang:byte_size(S), - fun(Input, Index) -> - try - <> = Input, - {S, Rest, p_advance_index(S, Index)} - catch - error:{badmatch, _} -> {fail, {expected, {string, S}, Index}} - end - end. --endif. - --ifdef(p_anything). --spec p_anything() -> parse_fun(). -p_anything() -> - fun(<<>>, Index) -> {fail, {expected, any_character, Index}}; - (Input, Index) when is_binary(Input) -> - <> = Input, - {<>, Rest, p_advance_index(<>, Index)} - end. --endif. - --ifdef(p_charclass). --spec p_charclass(string() | binary()) -> parse_fun(). -p_charclass(Class) -> - {ok, RE} = re:compile(Class, [unicode, dotall]), - fun(Inp, Index) -> - case re:run(Inp, RE, [anchored]) of - {match, [{0, Length} | _]} -> - {Head, Tail} = erlang:split_binary(Inp, Length), - {Head, Tail, p_advance_index(Head, Index)}; - _ -> {fail, {expected, {character_class, binary_to_list(Class)}, Index}} - end - end. --endif. - --ifdef(p_regexp). --spec p_regexp(binary()) -> parse_fun(). -p_regexp(Regexp) -> - {ok, RE} = re:compile(Regexp, [unicode, dotall, anchored]), - fun(Inp, Index) -> - case re:run(Inp, RE) of - {match, [{0, Length} | _]} -> - {Head, Tail} = erlang:split_binary(Inp, Length), - {Head, Tail, p_advance_index(Head, Index)}; - _ -> {fail, {expected, {regexp, binary_to_list(Regexp)}, Index}} - end - end. --endif. - --ifdef(line). --spec line(index() | term()) -> pos_integer() | undefined. -line({{line, L}, _}) -> L; -line(_) -> undefined. --endif. - --ifdef(column). --spec column(index() | term()) -> pos_integer() | undefined. -column({_, {column, C}}) -> C; -column(_) -> undefined. --endif. - --spec p_advance_index(input() | unicode:charlist() | pos_integer(), index()) -> index(). -p_advance_index(MatchedInput, Index) when is_list(MatchedInput) orelse is_binary(MatchedInput) -> % strings - lists:foldl(fun p_advance_index/2, Index, unicode:characters_to_list(MatchedInput)); -p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -> % single characters - {{line, Line}, {column, Col}} = Index, - case MatchedInput of - $\n -> {{line, Line + 1}, {column, 1}}; - _ -> {{line, Line}, {column, Col + 1}} - end.