• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
      • Kestrel-books
        • Crypto-hdwallet
        • Apt
        • Error-checking
        • Fty-extensions
        • Isar
        • Kestrel-utilities
        • Set
        • Soft
        • C
          • Syntax-for-tools
            • Disambiguator
            • Abstract-syntax
            • Parser
              • Parse-exprs/decls/stmts
              • Check-full-ppnumber
                • Read-char
                • Parstate
                • Lex-identifier/keyword
                • Lex-oct-iconst-/-dec-fconst
                • Lex-lexeme
                • Parse-external-declaration
                • Parse-cast-expression
                • Lex-isuffix-if-present
                • Parse-expression-or-type-name
                • Parse-postfix-expression
                • Lex-hex-iconst/fconst
                • Lex-dec-iconst/fconst
                • Lex-block-comment
                • Lex-escape-sequence
                • Read-token
                • Token
                • Lex-*-hexadecimal-digit
                • Lex-*-c-char
                • Lex-*-s-char
                • Parse-specifier/qualifier
                • Lex-*-digit
                • Lex-line-comment
                • Char-to-msg
                • Parse-primary-expression
                • Parse-declaration-specifier
                • Lex-iconst/fconst
                • Parse-external-declaration-list
                • Parse-declaration-specifiers
                • Lex-dec-expo-if-present
                • Init-parstate
                • Reread-to-token
                • Parse-asm-name-specifier
                • Lex-character-constant
                • Parse-expression-rest
                • Parstate$
                • Lex-dec-fconst
                • Token-unary-expression-start-p
                • Parse-declarator-or-abstract-declarator
                • Parse-asm-goto-labels
                • Parse-asm-clobbers
                • Lex-stringlit
                • Lex-non-octal-digit
                • Position
                • Lexeme
                • Lex-fsuffix-if-present
                • Parse-translation-unit
                • Lex-hexadecimal-digit
                • Token-type-specifier-keyword-p
                • Token-postfix-expression-rest-start-p
                • To-parstate$
                • Parse-?-asm-name-specifier
                • Parse-postfix-expression-rest
                • Parse-expression
                • Make-expr-unary-with-preinc/predec-ops
                • Lex-sign-if-present
                • Lex-dec-expo
                • Lex-bin-expo
                • Unread-to-token
                • Parse-*-stringlit
                • Parse-statement
                • Parse-fileset
                • Token-option
                • Lexeme-option
                • Token-struct-declaration-start-p
                • Parse-*-attribute-specifier
                • Parse-initializer-list
                • Parse-file
                • Parse-pointer
                • Parse-array/function-declarator
                • Unread-chars
                • Span
                • Read-stringlit
                • Lex-hex-quad
                • Unread-tokens
                • Token-type-qualifier-p
                • Read-identifier
                • Parse-*-asm-qualifier
                • Unread-char
                • Parse-attribute-name
                • Parse-argument-expressions
                • Make-expr-cast/add-or-cast/sub-ambig
                • Read-punctuator
                • Parse-struct-or-union-specifier
                • Parse-assignment-expression
                • Parse-asm-clobber
                • Token-specifier/qualifier-start-p
                • Token-primary-expression-start-p
                • Token-function-specifier-p
                • Reterr-msg
                • Read-keyword
                • Parse-*-increment/decrement
                • Parse-direct-abstract-declarator
                • Parse-declaration-or-statement
                • Char+position
                • Unread-token
                • Token+span
                • Token-expression-start-p
                • Update-parstate->tokens-unread
                • Update-parstate->chars-unread
                • Token-to-msg
                • Update-parstate->tokens-read
                • Update-parstate->tokens-length
                • Update-parstate->position
                • Update-parstate->chars-read
                • Parse-parameter-declaration
                • Parse-argument-expressions-rest
                • Update-parstate->chars-length
                • Token-to-type-specifier-keyword
                • Update-parstate->bytes
                • Parse-unary-expression
                • Parse-generic-associations-rest
                • Parse-conditional-expression
                • Update-parstate->size
                • Update-parstate->gcc
                • Parsize
                • Parse-direct-abstract-declarator-rest
                • Token-declaration-specifier-start-p
                • Parse-designator-list
                • Token-designation?-initializer-start-p
                • Token-abstract-declarator-start-p
                • Parse-?-asm-output-operands
                • Parse-?-asm-input-operands
                • Parse-struct-declaration
                • Parse-specifier-qualifier-list
                • Parse-parameter-declaration-list
                • Parse-constant-expression
                • Token-type-specifier-start-p
                • Token-type-qualifier-or-attribute-specifier-start-p
                • Parse-static-assert-declaration
                • Parse-fileset-loop
                • Parse-direct-declarator
                • Parse-declaration
                • Parse-attribute-parameters
                • Token-unary-operator-p
                • Token-to-unary-operator
                • Token-to-type-qualifier
                • Token-storage-class-specifier-p
                • Token-punctuatorp
                • Token-direct-abstract-declarator-start-p
                • Token-declarator-start-p
                • Parse-direct-declarator-rest
                • Token-to-storage-class-specifier
                • Token-to-assignment-operator
                • Token-to-asm-qualifier
                • Token-struct-declarator-start-p
                • Token-keywordp
                • Token-initializer-start-p
                • Token-direct-declarator-start-p
                • Token-assignment-operator-p
                • Parse-type-qualifier-and-attribute-specifier-list
                • Parse-enumerator-list
                • Parse-designation?-initializer
                • Parse-compound-literal
                • Parse-block-item
                • Token-type-name-start-p
                • Token-to-function-specifier
                • Token-preinc/predec-operator-p
                • Token-multiplicative-operator-p
                • Token-designator-start-p
                • Token-designation-start-p
                • Parstate->tokens-unread
                • Parstate->chars-unread
                • Parstate->bytes
                • Parse-initializer
                • Parse-generic-association
                • Parse-declaration-list
                • Parse-attribute-specifier
                • Parse-asm-output-operands
                • Token-to-relational-operator
                • Token-to-preinc/predec-operator
                • Token-to-multiplicative-operator
                • Token-relational-operator-p
                • Token-equality-operator-p
                • Token-asm-qualifier-p
                • Token-additive-operator-p
                • Span-join
                • Parstate->tokens-read
                • Parstate->tokens-length
                • Parstate->size
                • Parstate->chars-read
                • Parstate->chars-length
                • Parse-asm-statement
                • Parse-asm-input-operands
                • Update-parstate->token
                • Update-parstate->char
                • Token-to-equality-operator
                • Token-to-additive-operator
                • Token-shift-operator-p
                • To-parstate$-tokens-unread
                • To-parstate$-chars-unread
                • Position-inc-line
                • Position-inc-column
                • Parstate->gcc
                • Parse-type-name
                • Parse-struct-declarator-list
                • Parse-struct-declaration-list
                • Parse-relational-expression-rest
                • Parse-multiplicative-expression-rest
                • Parse-logical-or-expression-rest
                • Parse-logical-and-expression-rest
                • Parse-inclusive-or-expression-rest
                • Parse-exclusive-or-expression-rest
                • Parse-equality-expression-rest
                • Parse-array/function-abstract-declarator
                • Parse-additive-expression-rest
                • Token-to-shift-operator
                • To-parstate$-tokens-read
                • Parse-struct-declarator
                • Parse-shift-expression-rest
                • Parse-member-designor
                • Parse-init-declarator-list
                • Parse-init-declarator
                • Parse-and-expression-rest
                • Parse-alignment-specifier
                • To-parstate$-chars-read
                • Position-to-msg
                • Parstate->token
                • Parstate->char
                • Parse-shift-expression
                • Parse-relational-expression
                • Parse-multiplicative-expression
                • Parse-logical-or-expression
                • Parse-logical-and-expression
                • Parse-inclusive-or-expression
                • Parse-exclusive-or-expression
                • Parse-equality-expression
                • Parse-enum-specifier
                • Parse-block-item-list
                • Parse-attribute-list
                • Parse-and-expression
                • Parse-additive-expression
                • Parse-abstract-declarator
                • Char+position-list
                • Token+span-list
                • Span-to-msg
                • Parstate-fix
                • Parse-member-designor-rest
                • Position-init
                • Parstate->position
                • Parse-designator
                • Parse-declarator
                • Parse-attribute
                • Irr-token
                • Irr-span
                • Irr-position
                • Irr-lexeme
                • Token-list
                • Parse-type-qualifier-or-attribute-specifier
                • Parse-enumerator
                • Parse-asm-output-operand
                • Parse-asm-input-operand
              • Validator
              • Printer
              • Formalized-subset
              • Mapping-to-language-definition
              • Input-files
              • Defpred
              • Output-files
              • Abstract-syntax-operations
              • Validation-information
              • Implementation-environments
              • Concrete-syntax
              • Unambiguity
              • Ascii-identifiers
              • Preprocessing
              • Abstraction-mapping
            • Atc
            • Language
            • Representation
            • Transformation-tools
            • Insertion-sort
            • Pack
          • Bv
          • Imp-language
          • Event-macros
          • Java
          • Bitcoin
          • Ethereum
          • Yul
          • Zcash
          • ACL2-programming-language
          • Prime-fields
          • Json
          • Syntheto
          • File-io-light
          • Cryptography
          • Number-theory
          • Lists-light
          • Axe
          • Builtins
          • Solidity
          • Helpers
          • Htclient
          • Typed-lists-light
          • Arithmetic-light
        • X86isa
        • Axe
        • Execloader
      • Math
      • Testing-utilities
    • Parser

    Check-full-ppnumber

    Check that the numerical constant just read is a full preprocessing number.

    Signature
    (check-full-ppnumber ends-in-e parstate) 
      → 
    (mv erp new-parstate)
    Arguments
    ends-in-e — Guard (booleanp ends-in-e).
    parstate — Guard (parstatep parstate).
    Returns
    new-parstate — Type (parstatep new-parstate), given (parstatep parstate).

    In C, integer and floating constants are not lexed ``directly'' according to their grammar rules in [C17]. First, preprocessing tokens must be recognized, defined by preprocessing-token in [C17:6.4] [C17:A.1.1]. These include preprocessing numbers, defined by pp-number in [C17:6.4.8] [C17:A.1.9], which start with a digit, optionally preceded by a dot, and are followed by identifier characters (including digits and letter), as well as plus and minus signs immediately preceded by exponent letters, as well as periods [C17:6.4.8/2]. Thus, preprocessing numbers lexically include all integer and floating constants [C17:6.4.8/3], and much more, e.g. 638xyyy.e+E-.

    As part of translation phase 7 [C17:5.1.1.2], preprocessing tokens are converted to tokens. This includes converting preprocessing numbers to integer and floating constants, checking that they are in fact integer or floating constants, e.g. the example above would not pass the checks.

    In our lexer, we lex integer and floating constants directly, but we need to ensure that the behavior is the same as if we had gone through preprocessing numbers. We do that as follow: after fully recognizing an integer or floating constant, we check whether there is a subsequent character of the kind that would be part of a preprocessing number: if there is, it is an error, because the preprocessing number cannot be converted to a constant, due to the extra character(s).

    This function performs this check. It is called after an integer or floating constant has been recognized completely during lexing. This function attempts to read the next character, and unless there is no next character, or the next character is one that would not be part of the preprocessing number, an error is returned. In case of success, there is no additional result (it is just a check), except for the possibly updated parser state.

    If the next character exists and is a letter or a digit or an underscore or a dot, it would be part of the preprocessing number, so we return an error. Otherwise, the check succeeds, except in one case. The case is that the next character is + or -, but the last character of the integer or floating constant just read (before calling this function) is e or E: in that case, according to the grammar rule of pp-number in [C17], the e+ or e- or -E+ or E- would be part of the preprocessing number, and thus it would cause an error: so the check in this function fails in this case. This function takes a flag saying whether the last character of the read integer or floating constant was e or E; it is passed by the caller, who has read that constant.

    Note that, because of the rules on preprocessing numbers, in C this code is syntactically illegal

    int x = 0xe+1; // illegal

    whereas this code is syntactically legal

    int x = 0xf+1; // legal

    The reason is that 0xe+1 is a whole preprocessing number, while 0xf+1 is not; the latter is initially lexed as the preprocessing number 0xf followed by the punctuator + followed by the preprocesing number 1. These three can all be successfully converted fron preprocessing tokens to tokens; in particular, 0xf is a valid hexadecimal integer constant. But 0xe+1 is not a hexadecimal (or integer) constant, and so it cannot be converted to one.

    Definitions and Theorems

    Function: check-full-ppnumber

    (defun check-full-ppnumber (ends-in-e parstate)
     (declare (xargs :stobjs (parstate)))
     (declare (xargs :guard (and (booleanp ends-in-e)
                                 (parstatep parstate))))
     (let ((__function__ 'check-full-ppnumber))
      (declare (ignorable __function__))
      (b*
       (((reterr) parstate)
        ((erp char pos parstate)
         (read-char parstate))
        ((when (not char)) (retok parstate))
        ((when (or (and (<= (char-code #\A) char)
                        (<= char (char-code #\Z)))
                   (and (<= (char-code #\a) char)
                        (<= char (char-code #\a)))
                   (and (<= (char-code #\0) char)
                        (<= char (char-code #\9)))
                   (= char (char-code #\_))
                   (= char (char-code #\.))
                   (and ends-in-e
                        (or (= char (char-code #\+))
                            (= char (char-code #\-))))))
         (reterr-msg
          :where (position-to-msg pos)
          :expected
          (msg
           "a character other than ~
                                        a letter ~
                                        or a digit ~
                                        or an underscore ~
                                        or a dot~s0"
           (if ends-in-e " or a plus or a minus"
             ""))
          :found (char-to-msg char)))
        (parstate (unread-char parstate)))
       (retok parstate))))

    Theorem: parstatep-of-check-full-ppnumber.new-parstate

    (defthm parstatep-of-check-full-ppnumber.new-parstate
      (implies (parstatep parstate)
               (b* (((mv acl2::?erp ?new-parstate)
                     (check-full-ppnumber ends-in-e parstate)))
                 (parstatep new-parstate)))
      :rule-classes :rewrite)

    Theorem: parsize-of-check-full-ppnumber-uncond

    (defthm parsize-of-check-full-ppnumber-uncond
      (b* (((mv acl2::?erp ?new-parstate)
            (check-full-ppnumber ends-in-e parstate)))
        (<= (parsize new-parstate)
            (parsize parstate)))
      :rule-classes :linear)