parser.yy 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
  2. Permission to use, copy, modify, and/or distribute this software for any
  3. purpose with or without fee is hereby granted, provided that the above
  4. copyright notice and this permission notice appear in all copies.
  5. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  6. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  7. AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  8. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  9. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  10. OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  11. PERFORMANCE OF THIS SOFTWARE. */
  12. %skeleton "lalr1.cc" /* -*- C++ -*- */
  13. %require "3.0.0"
  14. %defines
  15. %define parser_class_name {EvalParser}
  16. %define api.token.constructor
  17. %define api.value.type variant
  18. %define api.namespace {isc::eval}
  19. %define parse.assert
  20. %code requires
  21. {
  22. #include <string>
  23. #include <eval/token.h>
  24. #include <eval/eval_context_decl.h>
  25. #include <boost/lexical_cast.hpp>
  26. using namespace isc::dhcp;
  27. using namespace isc::eval;
  28. }
  29. // The parsing context.
  30. %param { EvalContext& ctx }
  31. %locations
  32. %define parse.trace
  33. %define parse.error verbose
  34. %code
  35. {
  36. # include "eval_context.h"
  37. }
  38. %define api.token.prefix {TOKEN_}
  39. %token
  40. END 0 "end of file"
  41. EQUAL "=="
  42. OPTION "option"
  43. SUBSTRING "substring"
  44. TEXT "text"
  45. HEX "hex"
  46. ALL "all"
  47. DOT "."
  48. COMA ","
  49. LPAREN "("
  50. RPAREN ")"
  51. LBRACKET "["
  52. RBRACKET "]"
  53. ;
  54. %token <std::string> STRING "constant string"
  55. %token <std::string> INTEGER "integer"
  56. %token <std::string> HEXSTRING "constant hexstring"
  57. %token <std::string> TOKEN
  58. %printer { yyoutput << $$; } <*>;
  59. %code
  60. {
  61. namespace {
  62. /* Convert option code specified as string to an 16 bit unsigned
  63. representation. If the option code is not within the range of
  64. 0..65535 an error is reported. */
  65. uint16_t
  66. convert_option_code(const std::string& option_code,
  67. const isc::eval::EvalParser::location_type& loc,
  68. EvalContext& ctx) {
  69. int n = 0;
  70. try {
  71. n = boost::lexical_cast<int>(option_code);
  72. } catch (const boost::bad_lexical_cast &) {
  73. // This can't happen...
  74. ctx.error(loc, "Option code has invalid value in " + option_code);
  75. }
  76. if (n < 0 || n > 65535) {
  77. ctx.error(loc, "Option code has invalid value in "
  78. + option_code + ". Allowed range: 0..65535");
  79. }
  80. return (static_cast<uint16_t>(n));
  81. }
  82. }
  83. }
  84. %%
  85. // The whole grammar starts with an expression.
  86. %start expression;
  87. // Expression can either be a single token or a (something == something) expression
  88. expression : bool_expr
  89. ;
  90. bool_expr : string_expr EQUAL string_expr
  91. {
  92. TokenPtr eq(new TokenEqual());
  93. ctx.expression.push_back(eq);
  94. }
  95. ;
  96. string_expr : STRING
  97. {
  98. TokenPtr str(new TokenString($1));
  99. ctx.expression.push_back(str);
  100. }
  101. | HEXSTRING
  102. {
  103. TokenPtr hex(new TokenHexString($1));
  104. ctx.expression.push_back(hex);
  105. }
  106. | OPTION "[" INTEGER "]" DOT TEXT
  107. {
  108. uint16_t numeric_code = convert_option_code($3, @3, ctx);
  109. TokenPtr opt(new TokenOption(numeric_code, TokenOption::TEXTUAL));
  110. ctx.expression.push_back(opt);
  111. }
  112. | OPTION "[" INTEGER "]" DOT HEX
  113. {
  114. uint16_t numeric_code = convert_option_code($3, @3, ctx);
  115. TokenPtr opt(new TokenOption(numeric_code, TokenOption::HEXADECIMAL));
  116. ctx.expression.push_back(opt);
  117. }
  118. | SUBSTRING "(" string_expr "," start_expr "," length_expr ")"
  119. {
  120. TokenPtr sub(new TokenSubstring());
  121. ctx.expression.push_back(sub);
  122. }
  123. | TOKEN
  124. // Temporary unused token to avoid explict but long errors
  125. ;
  126. start_expr : INTEGER
  127. {
  128. TokenPtr str(new TokenString($1));
  129. ctx.expression.push_back(str);
  130. }
  131. ;
  132. length_expr : INTEGER
  133. {
  134. TokenPtr str(new TokenString($1));
  135. ctx.expression.push_back(str);
  136. }
  137. | ALL
  138. {
  139. TokenPtr str(new TokenString("all"));
  140. ctx.expression.push_back(str);
  141. }
  142. ;
  143. %%
  144. void
  145. isc::eval::EvalParser::error(const location_type& loc,
  146. const std::string& what)
  147. {
  148. ctx.error(loc, what);
  149. }