Files
NE_YuR/openflow/include/ovn/lex.h

152 lines
5.1 KiB
C

/*
* Copyright (c) 2015, 2016, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OVN_LEX_H
#define OVN_LEX_H 1
/* OVN lexical analyzer
* ====================
*
* This is a simple lexical analyzer (or tokenizer) for OVN match expressions
* and ACLs. */
#include "openvswitch/meta-flow.h"
struct ds;
/* Token type. */
enum lex_type {
LEX_T_END, /* end of input */
/* Tokens with auxiliary data. */
LEX_T_ID, /* foo */
LEX_T_STRING, /* "foo" */
LEX_T_INTEGER, /* 12345 or 1.2.3.4 or ::1 or 01:02:03:04:05 */
LEX_T_MASKED_INTEGER, /* 12345/10 or 1.2.0.0/16 or ::2/127 or... */
LEX_T_MACRO, /* $NAME */
LEX_T_ERROR, /* invalid input */
/* Bare tokens. */
LEX_T_LPAREN, /* ( */
LEX_T_RPAREN, /* ) */
LEX_T_LCURLY, /* { */
LEX_T_RCURLY, /* } */
LEX_T_LSQUARE, /* [ */
LEX_T_RSQUARE, /* ] */
LEX_T_EQ, /* == */
LEX_T_NE, /* != */
LEX_T_LT, /* < */
LEX_T_LE, /* <= */
LEX_T_GT, /* > */
LEX_T_GE, /* >= */
LEX_T_LOG_NOT, /* ! */
LEX_T_LOG_AND, /* && */
LEX_T_LOG_OR, /* || */
LEX_T_ELLIPSIS, /* .. */
LEX_T_COMMA, /* , */
LEX_T_SEMICOLON, /* ; */
LEX_T_EQUALS, /* = */
LEX_T_EXCHANGE, /* <-> */
LEX_T_DECREMENT, /* -- */
LEX_T_COLON, /* : */
};
/* Subtype for LEX_T_INTEGER and LEX_T_MASKED_INTEGER tokens.
*
* These do not change the semantics of a token; instead, they determine the
* format used when a token is serialized back to a text form. That's
* important because 3232268289 is meaningless to a human whereas 192.168.128.1
* has some actual significance. */
enum lex_format {
LEX_F_DECIMAL,
LEX_F_HEXADECIMAL,
LEX_F_IPV4,
LEX_F_IPV6,
LEX_F_ETHERNET,
};
const char *lex_format_to_string(enum lex_format);
/* A token. */
struct lex_token {
/* One of LEX_*. */
enum lex_type type;
/* Meaningful for LEX_T_ID, LEX_T_STRING, LEX_T_ERROR, LEX_T_MACRO only.
* For these token types, 's' may point to 'buffer'; otherwise, it points
* to malloc()ed memory owned by the token.
*
* Must be NULL for other token types.
*
* For LEX_T_MACRO, 's' does not include the leading $. */
char *s;
/* LEX_T_INTEGER, LEX_T_MASKED_INTEGER only. */
enum lex_format format;
union {
/* LEX_T_INTEGER, LEX_T_MASKED_INTEGER only. */
struct {
union mf_subvalue value; /* LEX_T_INTEGER, LEX_T_MASKED_INTEGER. */
union mf_subvalue mask; /* LEX_T_MASKED_INTEGER only. */
};
/* LEX_T_ID, LEX_T_STRING, LEX_T_ERROR, LEX_T_MACRO only. */
char buffer[256];
};
};
void lex_token_init(struct lex_token *);
void lex_token_destroy(struct lex_token *);
void lex_token_swap(struct lex_token *, struct lex_token *);
void lex_token_strcpy(struct lex_token *, const char *s, size_t length);
void lex_token_strset(struct lex_token *, char *s);
void lex_token_vsprintf(struct lex_token *, const char *format, va_list args);
void lex_token_format(const struct lex_token *, struct ds *);
const char *lex_token_parse(struct lex_token *, const char *input,
const char **startp);
/* A lexical analyzer. */
struct lexer {
const char *input; /* Remaining input (not owned by lexer). */
const char *start; /* Start of current token in 'input'. */
struct lex_token token; /* Current token (owned by lexer). */
char *error; /* Error message, if any (owned by lexer). */
};
void lexer_init(struct lexer *, const char *input);
void lexer_destroy(struct lexer *);
enum lex_type lexer_get(struct lexer *);
enum lex_type lexer_lookahead(const struct lexer *);
bool lexer_match(struct lexer *, enum lex_type);
bool lexer_force_match(struct lexer *, enum lex_type);
bool lexer_match_id(struct lexer *, const char *id);
bool lexer_is_int(const struct lexer *);
bool lexer_get_int(struct lexer *, int *value);
bool lexer_force_int(struct lexer *, int *value);
bool lexer_force_end(struct lexer *);
void lexer_error(struct lexer *, const char *message, ...)
OVS_PRINTF_FORMAT(2, 3);
void lexer_syntax_error(struct lexer *, const char *message, ...)
OVS_PRINTF_FORMAT(2, 3);
char *lexer_steal_error(struct lexer *);
#endif /* ovn/lex.h */