PageRenderTime 474ms CodeModel.GetById 457ms RepoModel.GetById 1ms app.codeStats 0ms

/mordor/xml/xml_parser.rl

http://github.com/mozy/mordor
Unknown | 166 lines | 135 code | 31 blank | 0 comment | 0 complexity | 94b5b075289d657ecaf626f1dc5596f2 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright (c) 2009 - Mozy, Inc.
  2. #include "mordor/pch.h"
  3. #include "mordor/xml/parser.h"
  4. using namespace Mordor;
  5. %%{
  6. machine xml_parser;
  7. action mark { mark = fpc;}
  8. action done { fbreak; }
  9. prepush {
  10. prepush();
  11. }
  12. postpop {
  13. postpop();
  14. }
  15. Char = '\t' | '\n' | '\r' | [' '-255];
  16. S = (' ' | '\t' | '\r' | '\n')+;
  17. NameStartChar = ':' | [A-Z] | '_' | [a-z] | 0xC0..0xD6 | 0xD8..0xF6 | 0xF8..0xFF;
  18. NameChar = NameStartChar | '-' | '.' | [0-9] | 0xB7;
  19. Name = NameStartChar NameChar*;
  20. Names = Name (' ' Name)*;
  21. Nmtoken = NameChar+;
  22. Nmtokens = Nmtoken (' ' Nmtoken)*;
  23. CharData = [^<&]* - ([^<&]* ']]>' [^<&]*);
  24. action reference
  25. {
  26. m_handler.onReference(std::string(mark, fpc-mark));
  27. mark = NULL;
  28. }
  29. CharRef = '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';';
  30. EntityRef = '&' Name ';';
  31. Reference = (EntityRef | CharRef) >mark %reference;
  32. PEReference = '%' Name ';';
  33. action attrib_value
  34. {
  35. if (fpc != mark) {
  36. m_handler.onAttributeValue(std::string(mark, fpc-mark));
  37. mark = NULL;
  38. }
  39. }
  40. EntityValue = '"' ([^%&"] | PEReference | Reference)* '"' |
  41. "'" ([^%&'] | PEReference | Reference)* '"';
  42. AttValue = '"' [^"<]* >mark %attrib_value '"' |
  43. "'" [^'<]* >mark %attrib_value "'" ;
  44. SystemLiteral = ('"' [^"]* '"') | ("'" [^']* "'");
  45. PubidChar = ' ' | '\r' | '\n' | [a-zA-Z0-9] | ['()+,./:=?;!*#@$_%] | '-';
  46. PubidLiteral = '"' PubidChar* '"' | "'" (PubidChar* -- "'") "'";
  47. Comment = '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->';
  48. PITarget = Name - ([Xx][Mm][Ll]);
  49. PI = '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>';
  50. Misc = Comment | PI | S;
  51. Eq = S? '=' S?;
  52. VersionNum = '1.' [0-9]+;
  53. VersionInfo = S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"');
  54. EncName = [A-Za-z] ([A-Za-z0-9._] | '-')*;
  55. EncodingDecl = S 'encoding' Eq ('"' EncName '"' | "'" EncName "'");
  56. SDDecl = S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'));
  57. XMLDecl = '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>';
  58. ExternalID = 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral;
  59. #markupdecl = elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment;
  60. #intSubset = (markupdecl | DeclSep)*;
  61. intSubset = '';
  62. doctypedecl = '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>';
  63. prolog = XMLDecl? Misc* (doctypedecl Misc*)?;
  64. CDStart = '<![CDATA[';
  65. CData = (Char* - (Char* ']]>' Char*));
  66. CDEnd = ']]>';
  67. CDSect = CDStart CData CDEnd;
  68. action start_tag {
  69. m_handler.onStartTag(std::string(mark, fpc-mark));
  70. mark = NULL;
  71. }
  72. action end_tag {
  73. m_handler.onEndTag(std::string(mark, fpc-mark));
  74. mark = NULL;
  75. }
  76. action empty_tag {
  77. m_handler.onEmptyTag();
  78. }
  79. action attrib_name
  80. {
  81. m_handler.onAttributeName(std::string(mark, fpc-mark));
  82. mark = NULL;
  83. }
  84. Attribute = Name >mark %attrib_name Eq AttValue;
  85. STag = '<' Name >mark %start_tag (S Attribute)* S? '>';
  86. ETag = '</' Name >mark %end_tag S? '>';
  87. EmptyElemTag = '<' Name >mark %start_tag (S Attribute)* S? '/>' %empty_tag;
  88. action call_parse_content {
  89. fcall *xml_parser_en_parse_content;
  90. }
  91. element = EmptyElemTag | STag @call_parse_content; #content ETag;
  92. action inner_text
  93. {
  94. if (fpc != mark) {
  95. m_handler.onInnerText(std::string(mark, fpc-mark));
  96. mark = NULL;
  97. }
  98. }
  99. content = CharData? >mark %inner_text ((element | Reference | CDSect | PI | Comment) CharData? >mark %inner_text)*;
  100. action element_finished {
  101. fret;
  102. }
  103. parse_content := parse_content_lbl: content ETag @element_finished;
  104. document = prolog element Misc*;
  105. main := document;
  106. write data;
  107. }%%
  108. void
  109. XMLParser::init()
  110. {
  111. RagelParserWithStack::init();
  112. %% write init;
  113. }
  114. void
  115. XMLParser::exec()
  116. {
  117. #ifdef MSVC
  118. #pragma warning(push)
  119. #pragma warning(disable : 4244)
  120. #endif
  121. %% write exec;
  122. #ifdef MSVC
  123. #pragma warning(pop)
  124. #endif
  125. }
  126. bool
  127. XMLParser::final() const
  128. {
  129. return cs >= xml_parser_first_final;
  130. }
  131. bool
  132. XMLParser::error() const
  133. {
  134. return cs == xml_parser_error;
  135. }