github.com/aretext/aretext@v1.3.0/syntax/languages/p4_test.go (about)

     1  package languages
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  
     8  	"github.com/aretext/aretext/syntax/parser"
     9  )
    10  
    11  func TestP4ParseFunc(t *testing.T) {
    12  	testCases := []struct {
    13  		name     string
    14  		text     string
    15  		expected []TokenWithText
    16  	}{
    17  		{
    18  			name: "line comment",
    19  			text: "// comment",
    20  			expected: []TokenWithText{
    21  				{Text: "// comment", Role: parser.TokenRoleComment},
    22  			},
    23  		},
    24  		{
    25  			name: "block comment",
    26  			text: `
    27  /*
    28  comment
    29  block
    30  */`,
    31  			expected: []TokenWithText{
    32  				{Text: "/*\ncomment\nblock\n*/", Role: parser.TokenRoleComment},
    33  			},
    34  		},
    35  		{
    36  			name: "numbers",
    37  			text: `
    38  0
    39  7
    40  10
    41  123
    42  123_456
    43  0xDEADBEEF
    44  32w255
    45  32w0d255
    46  32w0xFF
    47  32s0xFF
    48  8w0b10101010
    49  8w0b_1010_1010
    50  8w170
    51  8s0b1010_1010
    52  16w0377
    53  16w0o377
    54  `,
    55  			expected: []TokenWithText{
    56  				{Text: "0", Role: parser.TokenRoleNumber},
    57  				{Text: "7", Role: parser.TokenRoleNumber},
    58  				{Text: "10", Role: parser.TokenRoleNumber},
    59  				{Text: "123", Role: parser.TokenRoleNumber},
    60  				{Text: "123_456", Role: parser.TokenRoleNumber},
    61  				{Text: "0xDEADBEEF", Role: parser.TokenRoleNumber},
    62  				{Text: "32w255", Role: parser.TokenRoleNumber},
    63  				{Text: "32w0d255", Role: parser.TokenRoleNumber},
    64  				{Text: "32w0xFF", Role: parser.TokenRoleNumber},
    65  				{Text: "32s0xFF", Role: parser.TokenRoleNumber},
    66  				{Text: "8w0b10101010", Role: parser.TokenRoleNumber},
    67  				{Text: "8w0b_1010_1010", Role: parser.TokenRoleNumber},
    68  				{Text: "8w170", Role: parser.TokenRoleNumber},
    69  				{Text: "8s0b1010_1010", Role: parser.TokenRoleNumber},
    70  				{Text: "16w0377", Role: parser.TokenRoleNumber},
    71  				{Text: "16w0o377", Role: parser.TokenRoleNumber},
    72  			},
    73  		},
    74  		{
    75  			name:     "decimal cannot start with underscore",
    76  			text:     `_123_456`,
    77  			expected: []TokenWithText{},
    78  		},
    79  		{
    80  			name: "preprocessor directive",
    81  			text: `#include <core.p4>`,
    82  			expected: []TokenWithText{
    83  				{Text: "#include <core.p4>", Role: p4TokenRolePreprocessorDirective},
    84  			},
    85  		},
    86  		{
    87  			name: "annotation with string",
    88  			text: `@name("foo") table t1 { }`,
    89  			expected: []TokenWithText{
    90  				{Text: `@name`, Role: p4TokenRoleAnnotation},
    91  				{Text: `"foo"`, Role: parser.TokenRoleString},
    92  				{Text: `table`, Role: parser.TokenRoleKeyword},
    93  			},
    94  		},
    95  		{
    96  			name: "if statement",
    97  			text: `if (hdr.ipv4.ecn == 1 || hdr.ipv4.ecn == 2)`,
    98  			expected: []TokenWithText{
    99  				{Text: `if`, Role: parser.TokenRoleKeyword},
   100  				{Text: `==`, Role: parser.TokenRoleOperator},
   101  				{Text: `1`, Role: parser.TokenRoleNumber},
   102  				{Text: `||`, Role: parser.TokenRoleOperator},
   103  				{Text: `==`, Role: parser.TokenRoleOperator},
   104  				{Text: `2`, Role: parser.TokenRoleNumber},
   105  			},
   106  		},
   107  		{
   108  			name: "state with transition select",
   109  			text: `
   110  state parse_ethernet {
   111      packet.extract(hdr.ethernet);
   112      transition select(hdr.ethernet.etherType) {
   113          TYPE_IPV4: parse_ipv4;
   114          default: accept;
   115      }
   116  }`,
   117  			expected: []TokenWithText{
   118  				{Text: `state`, Role: parser.TokenRoleKeyword},
   119  				{Text: `transition`, Role: parser.TokenRoleKeyword},
   120  				{Text: `select`, Role: parser.TokenRoleKeyword},
   121  				{Text: `:`, Role: parser.TokenRoleOperator},
   122  				{Text: `default`, Role: parser.TokenRoleKeyword},
   123  				{Text: `:`, Role: parser.TokenRoleOperator},
   124  			},
   125  		},
   126  		{
   127  			name: "typedef",
   128  			text: `typedef bit<32> ip4Addr_t;`,
   129  			expected: []TokenWithText{
   130  				{Text: `typedef`, Role: parser.TokenRoleKeyword},
   131  				{Text: `bit`, Role: parser.TokenRoleKeyword},
   132  				{Text: `<`, Role: parser.TokenRoleOperator},
   133  				{Text: `32`, Role: parser.TokenRoleNumber},
   134  				{Text: `>`, Role: parser.TokenRoleOperator},
   135  			},
   136  		},
   137  		{
   138  			name: "const",
   139  			text: `const bit<16> TYPE_IPV4 = 0x800;`,
   140  			expected: []TokenWithText{
   141  				{Text: `const`, Role: parser.TokenRoleKeyword},
   142  				{Text: `bit`, Role: parser.TokenRoleKeyword},
   143  				{Text: `<`, Role: parser.TokenRoleOperator},
   144  				{Text: `16`, Role: parser.TokenRoleNumber},
   145  				{Text: `>`, Role: parser.TokenRoleOperator},
   146  				{Text: `=`, Role: parser.TokenRoleOperator},
   147  				{Text: `0x800`, Role: parser.TokenRoleNumber},
   148  			},
   149  		},
   150  		{
   151  			name: "header",
   152  			text: `
   153  header ethernet_t {
   154      macAddr_t dstAddr;
   155      macAddr_t srcAddr;
   156      bit<16>   etherType;
   157  }
   158  `,
   159  			expected: []TokenWithText{
   160  				{Text: `header`, Role: parser.TokenRoleKeyword},
   161  				{Text: `bit`, Role: parser.TokenRoleKeyword},
   162  				{Text: `<`, Role: parser.TokenRoleOperator},
   163  				{Text: `16`, Role: parser.TokenRoleNumber},
   164  				{Text: `>`, Role: parser.TokenRoleOperator},
   165  			},
   166  		},
   167  	}
   168  
   169  	for _, tc := range testCases {
   170  		t.Run(tc.name, func(t *testing.T) {
   171  			tokens := ParseTokensWithText(P4ParseFunc(), tc.text)
   172  			assert.Equal(t, tc.expected, tokens)
   173  		})
   174  	}
   175  }