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 }