如何确定在ANTLR中选择了哪个备用节点

时间:2015-10-18 13:57:39

标签: java antlr4

假设我有以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Odot2</title>
  <!-- Latest compiled and minified CSS -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
</head>

<body>

  <nav class="navbar navbar-default">
    <div class="container-fluid">
      <div class="navbar-header">  
        <a class="navbar-brand" href="#">Odot2</a>
      </div>

      <div class="user-links collapse navbar-collapse">
        <ul class="nav navbar-nav navbar-right">
          <% if user_signed_in? %>
          <li role='presentation'><%= link_to('Logout', destroy_user_session_path,
              :method => :delete) %></li>
          <li role='presentation'><%= link_to('Edit registration', 
              edit_user_registration_path) %></li>
          <% else %>
          <li role='presentation'><%= link_to('Login', new_user_session_path) %></li>
          <li role='presentation'><%= link_to('Register', new_user_registration_path) %></li>
          <% end %>
        </ul>
      </div>

    </div>
  </nav>

  <div class="flash panel">
    <% flash.each do |type, message| %>
      <div class='<%= build_alert_classes(type) %>'>
        <%= message %>
      </div>
    <% end %>
  </div>

  <main>
    <div class="container-fluid">
      <%= yield %>
    </div>
  </main>
</body>
</html>

这些T_名称只是定义为“整数”,“char”等。

现在假设我在名为LittleLanguage的测试程序的exitVariableDeclaration方法中。我可以参考LittleLanguageLexer.T_INTEGER(等),但我看不出如何确定通过上下文找到了哪些类型。

我以为它会variableDeclaration: Identifier COLON Type SEMICOLON; Type: T_INTEGER | T_CHAR | T_STRING | T_DOUBLE | T_BOOLEAN; ,但这不会返回正确的值。我知道我可以使用context.Type().getSymbol().getType())但我真的不想做字符串比较。

我错过了什么?

由于

1 个答案:

答案 0 :(得分:6)

通过过早组合令牌,您正在丢失词法分析器中的信息。最好在解析器规则中结合使用:

variableDeclaration: Identifier COLON type SEMICOLON;
type: T_INTEGER | T_CHAR | T_STRING | T_DOUBLE | T_BOOLEAN;

现在,type是一个TerminalNode,其基础令牌实例具有唯一类型:

variableDeclarationContext ctx = .... ;
TerminalNode typeNode = (TerminalNode) ctx.type().getChild(0);

switch(typeNode.getSymbol().getType()) {
  case YourLexer.T_INTEGER:
     ...