PostgreSQL Source Code: src/backend/parser/scan.l File Reference (original) (raw)

443{whitespace} {

444

445 }

446

447{xcstart} {

448

451 BEGIN(xc);

452

453 yyless(2);

454 }

455

456{

457{xcstart} {

459

460 yyless(2);

461 }

462

463{xcstop} {

464 if (yyextra->xcdepth <= 0)

465 BEGIN(INITIAL);

466 else

468 }

469

470{xcinside} {

471

472 }

473

474{op_chars} {

475

476 }

477

478\*+ {

479

480 }

481

482<> {

483 yyerror("unterminated /* comment");

484 }

485} /* */

486

487{xbstart} {

488

489

490

491

492

493

495 BEGIN(xb);

498 }

static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner)

499{xhinside} |

500{xbinside} {

502 }

503<> { yyerror("unterminated bit string literal"); }

504

505{xhstart} {

506

507

508

509

510

511

513 BEGIN(xh);

516 }

517<> { yyerror("unterminated hexadecimal string literal"); }

518

519{xnstart} {

520

521

522

523

524 int kwnum;

525

527 yyless(1);

528

531 if (kwnum >= 0)

532 {

535 return yyextra->keyword_tokens[kwnum];

536 }

537 else

538 {

539

540 yylval->str = pstrdup("n");

541 return IDENT;

542 }

543 }

int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords)

static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)

544

545{xqstart} {

546 yyextra->warn_on_first_escape = true;

547 yyextra->saw_non_ascii = false;

549 if (yyextra->standard_conforming_strings)

550 BEGIN(xq);

551 else

552 BEGIN(xe);

554 }

555{xestart} {

556 yyextra->warn_on_first_escape = false;

557 yyextra->saw_non_ascii = false;

559 BEGIN(xe);

561 }

562{xusstart} {

564 if (yyextra->standard_conforming_strings)

566 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

567 errmsg("unsafe use of string constant with Unicode escapes"),

568 errdetail("String constants with Unicode escapes cannot be used when \"standard_conforming_strings\" is off."),

570 BEGIN(xus);

572 }

int errdetail(const char *fmt,...)

573

574<xb,xh,xq,xe,xus>{quote} {

575

576

577

578

579

580

581

582

583 yyextra->state_before_str_stop = YYSTATE;

584 BEGIN(xqs);

585 }

586{quotecontinue} {

587

588

589

590

591

592 BEGIN(yyextra->state_before_str_stop);

593 }

594{quotecontinuefail} |

595{other} |

596<> {

597

598

599

600

601

602 yyless(0);

603 BEGIN(INITIAL);

604

605 switch (yyextra->state_before_str_stop)

606 {

607 case xb:

608 yylval->str = litbufdup(yyscanner);

609 return BCONST;

610 case xh:

611 yylval->str = litbufdup(yyscanner);

612 return XCONST;

613 case xq:

614 case xe:

615

616

617

618

619 if (yyextra->saw_non_ascii)

622 false);

623 yylval->str = litbufdup(yyscanner);

624 return SCONST;

625 case xus:

626 yylval->str = litbufdup(yyscanner);

627 return USCONST;

628 default:

629 yyerror("unhandled previous state in xqs");

630 }

631 }

bool pg_verifymbstr(const char *mbstr, int len, bool noError)

static char * litbufdup(core_yyscan_t yyscanner)

632

633<xq,xe,xus>{xqdouble} {

635 }

636<xq,xus>{xqinside} {

638 }

639{xeinside} {

641 }

642{xeunicode} {

643 pg_wchar c = strtoul(yytext + 2, NULL, 16);

644

645

646

647

648

649

651

652

654

656

658 {

659 yyextra->utf16_first_part = c;

660 BEGIN(xeu);

661 }

663 yyerror("invalid Unicode surrogate pair");

664 else

static bool is_utf16_surrogate_first(pg_wchar c)

static bool is_utf16_surrogate_second(pg_wchar c)

static void addunicode(pg_wchar c, yyscan_t yyscanner)

666

667

669 }

670{xeunicode} {

671 pg_wchar c = strtoul(yytext + 2, NULL, 16);

672

673

675

677

679 yyerror("invalid Unicode surrogate pair");

680

static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)

682

684

685

687

688 BEGIN(xe);

689 }

690. |

691\n |

692<> {

693

695 yyerror("invalid Unicode surrogate pair");

696 }

697<xe,xeu>{xeunicodefail} {

698

701 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),

702 errmsg("invalid Unicode escape"),

703 errhint("Unicode escapes must be \\uXXXX or \\UXXXXXXXX."),

705 }

706{xeescape} {

707 if (yytext[1] == '\'')

708 {

713 (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),

714 errmsg("unsafe use of \\' in a string literal"),

715 errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),

717 }

720 yyscanner);

721 }

int pg_get_client_encoding(void)

@ BACKSLASH_QUOTE_SAFE_ENCODING

#define PG_ENCODING_IS_CLIENT_ONLY(_enc)

static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner)

static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner)

722{xeoctesc} {

723 unsigned char c = strtoul(yytext + 1, NULL, 8);

724

728 yyextra->saw_non_ascii = true;

729 }

730{xehexesc} {

731 unsigned char c = strtoul(yytext + 2, NULL, 16);

732

736 yyextra->saw_non_ascii = true;

737 }

738. {

739

741 }

742<xq,xe,xus><> { yyerror("unterminated quoted string"); }

743

744{dolqdelim} {

747 BEGIN(xdolq);

749 }

750{dolqfailed} {

752

753 yyless(1);

754

755 return yytext[0];

756 }

757{dolqdelim} {

758 if (strcmp(yytext, yyextra->dolqstart) == 0)

759 {

761 yyextra->dolqstart = NULL;

762 BEGIN(INITIAL);

763 yylval->str = litbufdup(yyscanner);

764 return SCONST;

765 }

766 else

767 {

768

769

770

771

772

775 }

776 }

777{dolqinside} {

779 }

780{dolqfailed} {

782 }

783. {

784

786 }

787<> { yyerror("unterminated dollar-quoted string"); }

788

789{xdstart} {

791 BEGIN(xd);

793 }

794{xuistart} {

796 BEGIN(xui);

798 }

799{xdstop} {

801

802 BEGIN(INITIAL);

803 if (yyextra->literallen == 0)

804 yyerror("zero-length delimited identifier");

808 yylval->str = ident;

809 return IDENT;

810 }

void truncate_identifier(char *ident, int len, bool warn)

811{dquote} {

812 BEGIN(INITIAL);

813 if (yyextra->literallen == 0)

814 yyerror("zero-length delimited identifier");

815

816 yylval->str = litbufdup(yyscanner);

817 return UIDENT;

818 }

819<xd,xui>{xddouble} {

821 }

822<xd,xui>{xdinside} {

824 }

825<xd,xui><> { yyerror("unterminated quoted identifier"); }

826

827{xufailed} {

829

831

832 yyless(1);

833

835 yylval->str = ident;

836 return IDENT;

837 }

char * downcase_truncate_identifier(const char *ident, int len, bool warn)

838

839{typecast} {

841 return TYPECAST;

842 }

843

844{dot_dot} {

846 return DOT_DOT;

847 }

848

849{colon_equals} {

851 return COLON_EQUALS;

852 }

853

854{equals_greater} {

856 return EQUALS_GREATER;

857 }

858

859{less_equals} {

861 return LESS_EQUALS;

862 }

863

864{greater_equals} {

866 return GREATER_EQUALS;

867 }

868

869{less_greater} {

870

872 return NOT_EQUALS;

873 }

874

875{not_equals} {

876

878 return NOT_EQUALS;

879 }

880

881{self} {

883 return yytext[0];

884 }

885

886{operator} {

887

888

889

890

891

892

894 char *slashstar = strstr(yytext, "/*");

895 char *dashdash = strstr(yytext, "--");

896

897 if (slashstar && dashdash)

898 {

899

900 if (slashstar > dashdash)

901 slashstar = dashdash;

902 }

903 else if (!slashstar)

904 slashstar = dashdash;

905 if (slashstar)

906 nchars = slashstar - yytext;

907

908

909

910

911

912

913

914

915

916 if (nchars > 1 &&

917 (yytext[nchars - 1] == '+' ||

918 yytext[nchars - 1] == '-'))

919 {

920 int ic;

921

922 for (ic = nchars - 2; ic >= 0; ic--)

923 {

924 char c = yytext[ic];

925 if (c == '~' || c == '!' || c == '@' ||

926 c == '#' || c == '^' || c == '&' ||

927 c == '|' || c == '`' || c == '?' ||

928 c == '%')

929 break;

930 }

931 if (ic < 0)

932 {

933

934

935

936

937 do {

938 nchars--;

939 } while (nchars > 1 &&

940 (yytext[nchars - 1] == '+' ||

941 yytext[nchars - 1] == '-'));

942 }

943 }

944

946

948 {

949

950 yyless(nchars);

951

952

953

954

955

956

957 if (nchars == 1 &&

958 strchr(",()[].;:+-*/%^<>=", yytext[0]))

959 return yytext[0];

960

961

962

963

964

965

966 if (nchars == 2)

967 {

968 if (yytext[0] == '=' && yytext[1] == '>')

969 return EQUALS_GREATER;

970 if (yytext[0] == '>' && yytext[1] == '=')

971 return GREATER_EQUALS;

972 if (yytext[0] == '<' && yytext[1] == '=')

973 return LESS_EQUALS;

974 if (yytext[0] == '<' && yytext[1] == '>')

975 return NOT_EQUALS;

976 if (yytext[0] == '!' && yytext[1] == '=')

977 return NOT_EQUALS;

978 }

979 }

980

981

982

983

984

985

986

988 yyerror("operator too long");

989

990 yylval->str = pstrdup(yytext);

991 return Op;

992 }

993

994{param} {

997

1001 yyerror("parameter number too large");

1002 yylval->ival = val;

1003 return PARAM;

1004 }

1005{param_junk} {

1007 yyerror("trailing junk after parameter");

1008 }

1009

1010{decinteger} {

1013 }

static int process_integer_literal(const char *token, YYSTYPE *lval, int base)

1014{hexinteger} {

1017 }

1018{octinteger} {

1021 }

1022{bininteger} {

1025 }

1026{hexfail} {

1028 yyerror("invalid hexadecimal integer");

1029 }

1030{octfail} {

1032 yyerror("invalid octal integer");

1033 }

1034{binfail} {

1036 yyerror("invalid binary integer");

1037 }

1038{numeric} {

1040 yylval->str = pstrdup(yytext);

1041 return FCONST;

1042 }

1043{numericfail} {

1044

1048 }

1049{real} {

1051 yylval->str = pstrdup(yytext);

1052 return FCONST;

1053 }

1054{realfail} {

1056 yyerror("trailing junk after numeric literal");

1057 }

1058{integer_junk} {

1060 yyerror("trailing junk after numeric literal");

1061 }

1062{numeric_junk} {

1064 yyerror("trailing junk after numeric literal");

1065 }

1066{real_junk} {

1068 yyerror("trailing junk after numeric literal");

1069 }

1070

1071

1072{identifier} {

1073 int kwnum;

1075

1077

1078

1081 if (kwnum >= 0)

1082 {

1085 return yyextra->keyword_tokens[kwnum];

1086 }

1087

1088

1089

1090

1091

1093 yylval->str = ident;

1094 return IDENT;

1095 }

1096

1097{other} {

1099 return yytext[0];

1100 }

1101

1102<> {

1104 yyterminate();

1105 }

1106

1107%%