日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

语法分析生成器 - LEX

發布時間:2025/3/13 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 语法分析生成器 - LEX 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【轉載】The Lex & Yacc Page

Lex - A Lexical Analyzer Generator

M. E. Lesk and E. Schmidt?


ABSTRACT

Lex helps write programs whose control flow is directed by instances of regular expressions in the input stream. It is well suited for editor-script type transformations and for segmenting input in preparation for a parsing routine.

?

Lex source is a table of regular expressions and corresponding program fragments. The table is translated to a program which reads an input stream, copying it to an output stream and partitioning the input into strings which match the given expressions. As each such string is recognized the corresponding program fragment is executed. The recognition of the expressions is performed by a deterministic finite automaton generated by Lex. The program fragments written by the user are executed in the order in which the corresponding regular expressions occur in the input stream.

?

The lexical analysis programs written with Lex accept ambiguous specifications and choose the longest match possible at each input point. If necessary, substantial lookahead is performed on the input, but the input stream will be backed up to the end of the current partition, so that the user has general freedom to manipulate it.

?

Lex can generate analyzers in either C or R aftor, a language which can be translated automatically to portable Fortran. It is available on the PDP-11 UNIX, Honeywell GCOS, and IBM OS systems. This manual, however, will only discuss generating analyzers in C on the UNIX system, which is the only supported form of Lex under UNIX Version 7. Lex is designed to simplify interfacing with Yacc, for those with access to this compiler-compiler system.

?

1. Introduction.

Lex is a program generator designed for lexical processing of character input streams. It accepts a high-level, problem oriented specification for character string matching, and produces a program in a general purpose language which recognizes regular expressions. The regular expressions are specified by the user in the source specifications given to Lex. The Lex written code recognizes these expressions in an input stream and partitions the input stream into strings matching the expressions. At the boundaries between strings program sections provided by the user are executed. The Lex source file associates the regular expressions and the program fragments. As each expression appears in the input to the program written by Lex, the corresponding fragment is executed.

?

The user supplies the additional code beyond expression matching needed to complete his tasks, possibly including code written by other generators. The program that recognizes the expressions is generated in the general purpose programming language employed for the user's program fragments. Thus, a high level expression language is provided to write the string expressions to be matched while the user's freedom to write actions is unimpaired. This avoids forcing the user who wishes to use a string manipulation language for input analysis to write processing programs in the same and often inappropriate string handling language.

?

Lex is not a complete language, but rather a generator representing a new language feature which can be added to different programming languages, called "host languages.'' Just as general purpose languages can produce code to run on different computer hardware, Lex can write code in different host languages. The host language is used for the output code generated by Lex and also for the program fragments added by the user. Compatible run-time libraries for the different host languages are also provided. This makes Lex adaptable to different environments and different users. Each application may be directed to the combination of hardware and host language appropriate to the task, the user's background, and the properties of local implementations. At present, the only supported host language is C, although Fortran (in the form of Ratfor [2] has been available in the past). Lex itself exists on UNIX, GCOS, and OS/370; but the code generated by Lex may be taken anywhere the appropriate compilers exist.

?

Lex turns the user's expressions and actions (called source in this memo) into the host general-purpose language; the generated program is named yylex. The yylex program will recognize expressions in a stream (called input in this memo) and perform the specified actions for each expression as it is detected. See Figure 1.

+-------+Source -> | Lex | -> yylex+-------++-------+Input -> | yylex | -> Output+-------+An overview of LexFigure 1

For a trivial example, consider a program to delete from the input all blanks or tabs at the ends of lines.

%%[ \t]+$ ;

is all that is required. The program contains a %% delimiter to mark the beginning of the rules, and one rule. This rule contains a regular expression which matches one or more instances of the characters blank or tab (written \t for visibility, in accordance with the C language convention) just prior to the end of a line. The brackets indicate the character class made of blank and tab; the + indicates “ one or more ...''; and the $ indicates ” end of line,'' as in QED. No action is specified, so the program generated by Lex (yylex) will ignore these characters. Everything else will be copied. To change any remaining string of blanks or tabs to a single blank, add another rule:

?

%%[ \t]+$ ;[ \t]+ printf(" ");

The finite automaton generated for this source will scan for both rules at once, observing at the termination of the string of blanks or tabs whether or not there is a newline character, and executing the desired rule action. The first rule matches all strings of blanks or tabs at the end of lines, and the second rule all remaining strings of blanks or tabs.

?

Lex can be used alone for simple transformations, or for analysis and statistics ?gathering on a lexical level. Lex can also be used with a parser generator to perform the lexical analysis phase; it is particularly easy to interface Lex and Yacc [3]. Lex programs recognize only regular expressions; Yacc writes parsers that accept a large class of context free grammars, but require a lower level analyzer to recognize input tokens. Thus, a combination of Lex and Yacc is often appropriate. When used as a preprocessor for a later parser generator, Lex is used to partition the input stream, and the parser generator assigns structure to the resulting pieces. The flow of control in such a case (which might be the first half of a compiler, for example) is shown in Figure 2. Additional programs, written by other generators or by hand, can be added easily to programs written by Lex.

?

lexical grammarrules rules| |v v+---------+ +---------+| Lex | | Yacc |+---------+ +---------+| |v v+---------+ +---------+Input -> | yylex | -> | yyparse | -> Parsed input+---------+ +---------+Lex with YaccFigure 2

Yacc users will realize that the name yylex is what Yacc expects its lexical analyzer to be named, so that the use of this name by Lex simplifies interfacing.

?

Lex generates a deterministic finite automaton from the regular expressions in the source [4]. The automaton is interpreted, rather than compiled, in order to save space. The result is still a fast analyzer. In particular, the time taken by a Lex program to recognize and partition an input stream is proportional to the length of the input. The number of Lex rules or the complexity of the rules is not important in determining speed, unless rules which include forward context require a significant amount of rescanning. What does increase with the number and complexity of rules is the size of the finite automaton, and therefore the size of the program generated by Lex.

?

In the program written by Lex, the user's fragments (representing the actions to be performed as each regular expression is found) are gathered as cases of a switch. The automaton interpreter directs the control flow. Opportunity is provided for the user to insert either declarations or additional statements in the routine containing the actions, or to add subroutines outside this action routine.

?

Lex is not limited to source which can be interpreted on the basis of one character look ahead. For example, if there are two rules, one looking for ab and another for abcdefg, and the input stream is abcdefh, Lex will recognize ab and leave the input pointer just before cd. . . Such backup is more costly than the processing of simpler languages.

?

2. Lex Source.

The general format of Lex source is:

{definitions}%%{rules}%%{user subroutines}

where the definitions and the user subroutines are often omitted. The second %% is optional, but the first is required to mark the beginning of the rules. The absolute minimum Lex program is thus

%%

?

(no definitions, no rules) which translates into a program which copies the input to the output unchanged.

?

In the outline of Lex programs shown above, the rules represent the user's control decisions; they are a table, in which the left column contains regular expressions (see section 3) and the right column contains actions, program fragments to be executed when the expressions are recognized. Thus an individual rule might appear

integer printf("found keyword INT");

to look for the string integer in the input stream and print the message "found keyword INT'' whenever it appears. In this example the host procedural language is C and the C library function printf is used to print the string. The end of the expression is indicated by the first blank or tab character. If the action is merely a single C expression, it can just be given on the right side of the line; if it is compound, or takes more than a line, it should be enclosed in braces. As a slightly more useful example, suppose it is desired to change a number of words from British to American spelling. Lex rules such as

?

colour printf("color");mechanise printf("mechanize");petrol printf("gas");

would be a start. These rules are not quite enough, since the word petroleum would become gaseum; a way of dealing with this will be described later.

?

3. Lex Regular Expressions.

The definitions of regular expressions are very similar to those in QED [5]. A regular expression specifies a set of strings to be matched. It contains text characters (which match the corresponding characters in the strings being compared) and operator characters (which specify repetitions, choices, and other features). The letters of the alphabet and the digits are always text characters; thus the regular expression

integer

matches the string integer wherever it appears and the expression

a57D

looks for the string a57D.

?

Operators. The operator characters are

" \ [ ] ^ - ? . * + | ( ) $ / { } % < >

and if they are to be used as text characters, an escape should be used. The quotation mark operator (") indicates that whatever is contained between a pair of quotes is to be taken as text characters. Thus

xyz"++"

matches the string xyz++ when it appears. Note that a part of a string may be quoted. It is harmless but unnecessary to quote an ordinary text character; the expression

"xyz++"

is the same as the one above. Thus by quoting every non-alphanumeric character being used as a text character, the user can avoid remembering the list above of current operator characters, and is safe should further extensions to Lex lengthen the list.

?

An operator character may also be turned into a text character by preceding it with \ as in

xyz\+\+

which is another, less readable, equivalent of the above expressions. Another use of the quoting mechanism is to get a blank into an expression; normally, as explained above, blanks or tabs end a rule. Any blank character not contained within [] (see below) must be quoted. Several normal C escapes with \ are recognized: \n is newline, \t is tab, and \b is backspace. To enter \ itself, use \\. Since newline is illegal in an expression, \n must be used; it is not required to escape tab and backspace. Every character but blank, tab, newline and the list above is always a text character.

?

Character classes. Classes of characters can be specified using the operator pair []. The construction [abc] matches a single character, which may be a, b, or c. Within square brackets, most operator meanings are ignored. Only three characters are special: these are \ - and ^. The - character indicates ranges. For example,

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[a-z0-9<>_]

?

indicates the character class containing all the lower case letters, the digits, the angle brackets, and underline. Ranges may be given in either order. Using - between any pair of characters which are not both upper case letters, both lower case letters, or both digits is implementation dependent and will get a warning message. (E.g., [0-z] in ASCII is many more characters than it is in EBCDIC). If it is desired to include the character - in a character class, it should be first or last; thus

?

[-+0-9]

?

matches all the digits and the two signs.

?

In character classes, the ^ operator must appear as the first character after the left bracket; it indicates that the resulting string is to be complemented with respect to the computer character set. Thus

?

[^abc]

?

matches all characters except a, b, or c, including all special or control characters; or

[^a-zA-Z]

?

is any character which is not a letter. The \ character provides the usual escapes within character class brackets.

Arbitrary character. To match almost any character, the operator character . is the class of all characters except newline. Escaping into octal is possible although non-portable:

[\40-\176]

matches all printable characters in the ASCII character set, from octal 40 (blank) to octal 176 (tilde).

Optional expressions. The operator ? indicates an optional element of an expression. Thus

ab?c

matches either ac or abc.

?

Repeated expressions. Repetitions of classes are indicated by the operators * and +.

a*

is any number of consecutive a characters, including zero; while

a+

?

is one or more instances of a. For example,

[a-z]+

?

is all strings of lower case letters. And

[A-Za-z][A-Za-z0-9]*

?

indicates all alphanumeric strings with a leading alphabetic character. This is a typical expression for recognizing identifiers in computer languages.

?

Alternation and Grouping. The operator | indicates alternation:

(ab|cd)

?

matches either ab or cd. Note that parentheses are used for grouping, although they are not necessary on the outside level;

ab|cd

?

would have sufficed. Parentheses can be used for more complex expressions:

(ab|cd+)?(ef)*

matches such strings as abefef, efefef, cdef, or cddd; but not abc, abcd, or abcdef.

?

Context sensitivity. Lex will recognize a small amount of surrounding context. The two simplest operators for this are ^ and $. If the first character of an expression is ^, the expression will only be matched at the beginning of a line (after a newline character, or at the beginning of the input stream). This can never conflict with the other meaning of ^, complementation of character classes, since that only applies within the [] operators. If the very last character is $, the expression will only be matched at the end of a line (when immediately followed by newline). The latter operator is a special case of the / operator character, which indicates trailing context. The expression

?

ab/cd

?

matches the string ab, but only if followed by cd. Thus

ab$

?

is the same as

ab/\n

?

Left context is handled in Lex by start conditions as explained in section 10. If a rule is only to be executed when the Lex automaton interpreter is in start condition x, the rule should be prefixed by

<x>

?

using the angle bracket operator characters. If we considered ``being at the beginning of a line'' to be start condition ONE, then the ^ operator would be equivalent to

<ONE>

?

Start conditions are explained more fully later.

?

Repetitions and Definitions. The operators {} specify either repetitions (if they enclose numbers) or definition expansion (if they enclose a name). For example

{digit}

looks for a predefined string named digit and inserts it at that point in the expression. The definitions are given in the first part of the Lex input, before the rules. In contrast,

a{1,5}

looks for 1 to 5 occurrences of a.

?

Finally, initial % is special, being the separator for Lex source segments.

?

4. Lex Actions.

When an expression written as above is matched, Lex executes the corresponding action. This section describes some features of Lex which aid in writing actions. Note that there is a default action, which consists of copying the input to the output. This is performed on all strings not otherwise matched. Thus the Lex user who wishes to absorb the entire input, without producing any output, must provide rules to match everything. When Lex is being used with Yacc, this is the normal situation. One may consider that actions are what is done instead of copying the input to the output; thus, in general, a rule which merely copies can be omitted. Also, a character combination which is omitted from the rules and which appears as input is likely to be printed on the output, thus calling attention to the gap in the rules.

?

One of the simplest things that can be done is to ignore the input. ?Specifying a C null statement, ; as an action causes this result. A frequent rule is

[ \t\n] ;

which causes the three spacing characters (blank, tab, and newline) to be ignored.

?

Another easy way to avoid writing actions is the action character |, which indicates that the action for this rule is the action for the next rule. The previous example could also have been written

?

" ""\t""\n"

with the same result, although in different style. The quotes around \n and \t are not required.

?

In more complex actions, the user will often want to know the actual text that matched some expression like [a-z]+. Lex leaves this text in an external character array named yytext. Thus, to print the name found, a rule like

[a-z]+ printf("%s", yytext);

will print the string in yytext. The C function printf accepts a format argument and data to be printed; in this case, the format is ``print string'' (% indicating data conversion, and s indicating string type), and the data are the characters in yytext. So this just places the matched string on the output. This action is so common that it may be written as ECHO:

?

[a-z]+ ECHO;

is the same as the above. Since the default action is just to print the characters found, one might ask why give a rule, like this one, which merely specifies the default action? Such rules are often required to avoid matching some other rule which is not desired. For example, if there is a rule which matches read it will normally match the instances of read contained in bread or readjust; to avoid this, a rule of the form [a-z]+ is needed. This is explained further below.

?

Sometimes it is more convenient to know the end of what has been found; hence Lex also provides a count yyleng of the number of characters matched. To count both the number of words and the number of characters in words in the input, the user might write [a-zA-Z]+ {words++; chars += yyleng;} which accumulates in chars the number of characters in the words recognized. The last character in the string matched can be accessed by

yytext[yyleng-1]

Occasionally, a Lex action may decide that a rule has not recognized the correct span of characters. Two routines are provided to aid with this situation. First, yymore() can be called to indicate that the next input expression recognized is to be tacked on to the end of this input. Normally, the next input string would overwrite the current entry in yytext. Second, yyless (n) may be called to indicate that not all the characters matched by the currently successful expression are wanted right now. The argument n indicates the number of characters in yytext to be retained. Further characters previously matched are returned to the input. This provides the same sort of lookahead offered by the / operator, but in a different form.

?

Example: Consider a language which defines a string as a set of characters between quotation (") marks, and provides that to include a " in a string it must be preceded by a \. The regular expression which matches that is somewhat confusing, so that it might be preferable to write

?

\"[^"]* {if (yytext[yyleng-1] == '\\')yymore();else... normal user processing}

which will, when faced with a string such as "abc\"def" first match the five characters "abc\; then the call to yymore() will cause the next part of the string, "def, to be tacked on the end. Note that the final quote terminating the string should be picked up in the code labeled ``normal processing''.

?

The function yyless() might be used to reprocess text in various circumstances. Consider the C problem of distinguishing the ambiguity of ``=-a''. Suppose it is desired to treat this as ``=- a'' but print a message. A rule might be

?

=-[a-zA-Z] {printf("Op (=-) ambiguous\n");yyless(yyleng-1);... action for =- ...}

which prints a message, returns the letter after the operator to the input stream, and treats the operator as ``=-''. Alternatively it might be desired to treat this as ``= -a''. To do this, just return the minus sign as well as the letter to the input:

?

=-[a-zA-Z] {printf("Op (=-) ambiguous\n");yyless(yyleng-2);... action for = ...}

will perform the other interpretation. Note that the expressions for the two cases might more easily be written

=-/[A-Za-z]

in the first case and

=/-[A-Za-z]

in the second; no backup would be required in the rule action. It is not necessary to recognize the whole identifier to observe the ambiguity. The possibility of ``=-3'', however, makes

?

=-/[^ \t\n]

a still better rule.

?

In addition to these routines, Lex also permits access to the I/O routines it uses. They are:

1) input() which returns the next input character;

2) output(c) which writes the character c on the output; and

3) unput(c) pushes the character c back onto the input stream to be read later by input().

?

By default these routines are provided as macro definitions, but the user can override them and supply private versions. These routines define the relationship between external files and internal characters, and must all be retained or modified consistently. They may be redefined, to cause input or output to be transmitted to or from strange places, including other programs or internal memory; but the character set used must be consistent in all routines; a value of zero returned by input must mean end of file; and the relationship between unput and input must be retained or the Lex lookahead will not work. Lex does not look ahead at all if it does not have to, but every rule ending in + * ? or $ or containing / implies lookahead. Lookahead is also necessary to match an expression that is a prefix of another expression. See below for a discussion of the character set used by Lex. The standard Lex library imposes a 100 character limit on backup.

?

Another Lex library routine that the user will sometimes want to redefine is yywrap() which is called whenever Lex reaches an end-of-file. If yywrap returns a 1, Lex continues with the normal wrapup on end of input. Sometimes, however, it is convenient to arrange for more input to arrive from a new source. In this case, the user should provide a yywrap which arranges for new input and returns 0. This instructs Lex to continue processing. The default yywrap always returns 1.

?

This routine is also a convenient place to print tables, summaries, etc. at the end of a program. Note that it is not possible to write a normal rule which recognizes end-of-file; the only access to this condition is through yywrap. In fact, unless a private version of input() is supplied a file containing nulls cannot be handled, since a value of 0 returned by input is taken to be end-of-file.

?

5. Ambiguous Source Rules.

Lex can handle ambiguous specifications. When more than one expression can match the current input, Lex chooses as follows:

1) The longest match is preferred.

2) Among rules which matched the same number of characters, the rule given first is preferred.

?

Thus, suppose the rules

integer keyword action ...;[a-z]+ identifier action ...;

?

to be given in that order. If the input is integers, it is taken as an identifier, because [a-z]+ matches 8 characters while integer matches only 7. If the input is integer, both rules match 7 characters, and the keyword rule is selected because it was given first. Anything shorter (e.g. int) will not match the expression integer and so the identifier interpretation is used.

?

The principle of preferring the longest match makes rules containing expressions like .* dangerous. For example, '.*' might seem a good way of recognizing a string in single quotes. But it is an invitation for the program to read far ahead, looking for a distant single quote. Presented with the input

?

'first' quoted string here, 'second' here

the above expression will match

'first' quoted string here, 'second'

?

which is probably not what was wanted. A better rule is of the form

'[^'\n]*'

?

which, on the above input, will stop after 'first'. The consequences of errors like this are mitigated by the fact that the . operator will not match newline. Thus expressions like .* stop on the current line. Don't try to defeat this with expressions like (.|\n)+ or equivalents; the Lex generated program will try to read the entire input file, causing internal buffer overflows.

?

Note that Lex is normally partitioning the input stream, not searching for all possible matches of each expression. This means that each character is accounted for once and only once. For example, suppose it is desired to count occurrences of both she and he in an input text. Some Lex rules to do this might be

she s++;he h++;\n |. ;

where the last two rules ignore everything besides he and she. Remember that . does not include newline. Since she includes he, Lex will normally not recognize the instances of he included in she, since once it has passed a she those characters are gone.

?

Sometimes the user would like to override this choice. The action REJECT means ``go do the next alternative.'' It causes whatever rule was second choice after the current rule to be executed. The position of the input pointer is adjusted accordingly. Suppose the user really wants to count the included instances of he:

she {s++; REJECT;}he {h++; REJECT;}\n |. ;

?

these rules are one way of changing the previous example to do just that. After counting each expression, it is rejected; whenever appropriate, the other expression will then be counted. In this example, of course, the user could note that she includes he but not vice versa, and omit the REJECT action on he; in other cases, however, it would not be possible a priori to tell which input characters were in both classes.

?

Consider the two rules

a[bc]+ { ... ; REJECT;}a[cd]+ { ... ; REJECT;}

?

If the input is ab, only the first rule matches, and on ad only the second matches. The input string accb matches the first rule for four characters and then the second rule for three characters. In contrast, the input accd agrees with the second rule for four characters and then the first rule for three.

?

In general, REJECT is useful whenever the purpose of Lex is not to partition the input stream but to detect all examples of some items in the input, and the instances of these items may overlap or include each other. Suppose a digram table of the input is desired; normally the digrams overlap, that is the word the is considered to contain both th and he. Assuming a two-dimensional array named digram to be incremented, the appropriate source is

?

%%[a-z][a-z] {digram[yytext[0]][yytext[1]]++;REJECT;}. ;\n ;

?

where the REJECT is necessary to pick up a letter pair beginning at every character, rather than at every other character.

?

6. Lex Source Definitions.

Remember the format of the Lex source:

{definitions}%%{rules}%%{user routines}

So far only the rules have been described. The user needs additional options, though, to define variables for use in his program and for use by Lex. These can go either in the definitions section or in the rules section.

?

Remember that Lex is turning the rules into a program. Any source not intercepted by Lex is copied into the generated program. There are three classes of such things.

?

1) Any line which is not part of a Lex rule or action which begins with a blank or tab is copied into the Lex generated program. Such source input prior to the first %% delimiter will be external to any function in the code; if it appears immediately after the first %%, it appears in an appropriate place for declarations in the function written by Lex which contains the actions. This material must look like program fragments, and should precede the first Lex rule. As a side effect of the above, lines which begin with a blank or tab, and which contain a comment, are passed through to the generated program. This can be used to include comments in either the Lex source or the generated code. The comments should follow the host language convention.

?

2) Anything included between lines containing only %{ and %} is copied out as above. The delimiters are discarded. This format permits entering text like preprocessor statements that must begin in column 1, or copying lines that do not look like programs.

?

3) Anything after the third %% delimiter, regardless of formats, etc., is copied out after the Lex output.

Definitions intended for Lex are given before the first %% delimiter. Any line in this section not contained between %{ and %}, and begining in column 1, is assumed to define Lex substitution strings. The format of such lines is name translation and it causes the string given as a translation to be associated with the name. The name and translation must be separated by at least one blank or tab, and the name must begin with a letter. The translation can then be called out by the {name} syntax in a rule. Using {D} for the digits and {E} for an exponent field, for example, might abbreviate rules to recognize numbers:

?

D [0-9]E [DEde][-+]?{D}+%%{D}+ printf("integer");{D}+"."{D}*({E})? |{D}*"."{D}+({E})? |{D}+{E}

?

Note the first two rules for real numbers; both require a decimal point and contain an optional exponent field, but the first requires at least one digit before the decimal point and the second requires at least one digit after the decimal point. To correctly handle the problem posed by a Fortran expression such as 35.EQ.I, which does not contain a real number, a context-sensitive rule such as

[0-9]+/"."EQ printf("integer");

?

could be used in addition to the normal rule for integers.

?

The definitions section may also contain other commands, including the selection of a host language, a character set table, a list of start conditions, or adjustments to the default size of arrays within Lex itself for larger source programs. These possibilities are discussed below under "Summary of Source Format,'' section 12.

?

7. Usage.

There are two steps in compiling a Lex source program. First, the Lex source must be turned into a generated program in the host general purpose language. Then this program must be compiled and loaded, usually with a library of Lex subroutines. The generated program is on a file named lex.yy.c. The I/O library is defined in terms of the C standard library [6].

?

The C programs generated by Lex are slightly different on OS/370, because the OS compiler is less powerful than the UNIX or GCOS compilers, and does less at compile time. C programs generated on GCOS and UNIX are the same.

?

UNIX. The library is accessed by the loader flag -ll. So an appropriate set of commands is lex source cc lex.yy.c -ll The resulting program is placed on the usual file a.out for later execution. To use Lex with Yacc see below. Although the default Lex I/O routines use the C standard library, the Lex automata themselves do not do so; if private versions of input, output and unput are given, the library can be avoided.

?

8. Lex and Yacc.

If you want to use Lex with Yacc, note that what Lex writes is a program named yylex(), the name required by Yacc for its analyzer. Normally, the default main program on the Lex library calls this routine, but if Yacc is loaded, and its main program is used, Yacc will call yylex(). In this case each Lex rule should end with

?

return(token);

?

where the appropriate token value is returned. An easy way to get access to Yacc's names for tokens is to compile the Lex output file as part of the Yacc output file by placing the line # include "lex.yy.c" in the last section of Yacc input. Supposing the grammar to be named ``good'' and the lexical rules to be named ``better'' the UNIX command sequence can just be:

yacc goodlex bettercc y.tab.c -ly -ll

?

The Yacc library (-ly) should be loaded before the Lex library, to obtain a main program which invokes the Yacc parser. The generations of Lex and Yacc programs can be done in either order.

?

9. Examples.

As a trivial problem, consider copying an input file while adding 3 to every positive number divisible by 7. Here is a suitable Lex source program

%%int k;[0-9]+ {k = atoi(yytext);if (k%7 == 0)printf("%d", k+3);elseprintf("%d",k);}

?

to do just that. The rule [0-9]+ recognizes strings of digits; atoi converts the digits to binary and stores the result in k. The operator % (remainder) is used to check whether k is divisible by 7; if it is, it is incremented by 3 as it is written out. It may be objected that this program will alter such input items as 49.63 or X7. Furthermore, it increments the absolute value of all negative numbers divisible by 7. To avoid this, just add a few more rules after the active one, as here:

%%int k;-?[0-9]+ {k = atoi(yytext);printf("%d",k%7 == 0 ? k+3 : k);}-?[0-9.]+ ECHO;[A-Za-z][A-Za-z0-9]+ ECHO;

?

Numerical strings containing a ``.'' or preceded by a letter will be picked up by one of the last two rules, and not changed. The if-else has been replaced by a C conditional expression to save space; the form a?b:c means ``if a then b else c''.

?

For an example of statistics gathering, here is a program which histograms the lengths of words, where a word is defined as a string of letters.

int lengs[100];%%[a-z]+ lengs[yyleng]++;. |\n ;%%yywrap(){int i;printf("Length No. words\n");for(i=0; i<100; i++)if (lengs[i] > 0)printf("%5d%10d\n",i,lengs[i]);return(1);}

?

This program accumulates the histogram, while producing no output. At the end of the input it prints the table. The final statement return(1); indicates that Lex is to perform wrapup. If yywrap returns zero (false) it implies that further input is available and the program is to continue reading and processing. To provide a yywrap that never returns true causes an infinite loop.

?

As a larger example, here are some parts of a program written by N. L. Schryer to convert double precision Fortran to single precision Fortran. Because Fortran does not distinguish upper and lower case letters, this routine begins by defining a set of classes including both cases of each letter:

a [aA]b [bB]c [cC]...z [zZ]

An additional class recognizes white space:

W [ \t]*

The first rule changes ``double precision'' to ``real'', or ``DOUBLE PRECISION'' to ``REAL''.

ozvdkddzhkzd{o}{u}{b}{l}{e}{W}{p}{r}{e}{c}{i}{s}{i}{o}{n} {printf(yytext[0]=='d'? "real" : "REAL");}

Care is taken throughout this program to preserve the case (upper or lower) of the original program. The conditional operator is used to select the proper form of the keyword. The next rule copies continuation card indications to avoid confusing them with constants:

^" "[^ 0] ECHO;

In the regular expression, the quotes surround the blanks. It is interpreted as ``beginning of line, then five blanks, then anything but blank or zero.'' Note the two different meanings of ^. There follow some rules to change double precision constants to ordinary floating constants.

[0-9]+{W}ozvdkddzhkzd{W}[+-]?{W}[0-9]+ |[0-9]+{W}"."{W}ozvdkddzhkzd{W}[+-]?{W}[0-9]+ |"."{W}[0-9]+{W}ozvdkddzhkzd{W}[+-]?{W}[0-9]+ {/* convert constants */for(p=yytext; *p != 0; p++){if (*p == 'd' || *p == 'D')*p=+ 'e'- 'd';ECHO;}

After the floating point constant is recognized, it is scanned by the for loop to find the letter d or D. The program than adds 'e'-'d', which converts it to the next letter of the alphabet. The modified constant, now single-precision, is written out again. There follow a series of names which must be respelled to remove their initial d. By using the array yytext the same action suffices for all the names (only a sample of a rather long list is given here).

ozvdkddzhkzd{s}{i}{n} |ozvdkddzhkzd{c}{o}{s} |ozvdkddzhkzd{s}{q}{r}{t} |ozvdkddzhkzd{a}{t}{a}{n} |...ozvdkddzhkzd{f}{l}{o}{a}{t} printf("%s",yytext+1);

Another list of names must have initial d changed to initial a:

ozvdkddzhkzd{l}{o}{g} |ozvdkddzhkzd{l}{o}{g}10 |ozvdkddzhkzd{m}{i}{n}1 |ozvdkddzhkzd{m}{a}{x}1 {yytext[0] =+ 'a' - 'd';ECHO;}

And one routine must have initial d changed to initial r:

ozvdkddzhkzd1{m}{a}{c}{h} {yytext[0] =+ 'r' - 'd';

To avoid such names as dsinx being detected as instances of dsin, some final rules pick up longer words as identifiers and copy some surviving characters:

[A-Za-z][A-Za-z0-9]* |[0-9]+ |\n |. ECHO;

Note that this program is not complete; it does not deal with the spacing problems in Fortran or with the use of keywords as identifiers.

?

10. Left Context Sensitivity.

Sometimes it is desirable to have several sets of lexical rules to be applied at different times in the input. For example, a compiler preprocessor might distinguish preprocessor statements and analyze them differently from ordinary statements. This requires sensitivity to prior context, and there are several ways of handling such problems. The ^ operator, for example, is a prior context operator, recognizing immediately preceding left context just as $ recognizes immediately following right context. Adjacent left context could be extended, to produce a facility similar to that for adjacent right context, but it is unlikely to be as useful, since often the relevant left context appeared some time earlier, such as at the beginning of a line.

?

This section describes three means of dealing with different environments: a simple use of flags, when only a few rules change from one environment to another, the use of start conditions on rules, and the possibility of making multiple lexical analyzers all run together. In each case, there are rules which recognize the need to change the environment in which the following input text is analyzed, and set some parameter to reflect the change. This may be a flag explicitly tested by the user's action code; such a flag is the simplest way of dealing with the problem, since Lex is not involved at all. It may be more convenient, however, to have Lex remember the flags as initial conditions on the rules. Any rule may be associated with a start condition. It will only be recognized when Lex is in that start condition. The current start condition may be changed at any time. Finally, if the sets of rules for the different environments are very dissimilar, clarity may be best achieved by writing several distinct lexical analyzers, and switching from one to another as desired.

?

Consider the following problem: copy the input to the output, changing the word magic to first on every line which began with the letter a, changing magic to second on every line which began with the letter b, and changing magic to third on every line which began with the letter c. All other words and all other lines are left unchanged.

?

These rules are so simple that the easiest way to do this job is with a flag:

int flag;%%^a {flag = 'a'; ECHO;}^b {flag = 'b'; ECHO;}^c {flag = 'c'; ECHO;}\n {flag = 0 ; ECHO;}magic {switch (flag){case 'a': printf("first"); break;case 'b': printf("second"); break;case 'c': printf("third"); break;default: ECHO; break;}}

should be adequate.

?

To handle the same problem with start conditions, each start condition must be introduced to Lex in the definitions section with a line reading

%Start name1 name2 ...

where the conditions may be named in any order. The word Start may be abbreviated to s or S. The conditions may be referenced at the head of a rule with the <> brackets:

<name1>expression

is a rule which is only recognized when Lex is in the start condition name1. To enter a start condition, execute the action statement

BEGIN name1;

which changes the start condition to name1. To resume the normal state,

BEGIN 0;

resets the initial condition of the Lex automaton interpreter. A rule may be active in several start conditions: <name1,name2,name3> is a legal prefix. Any rule not beginning with the <> prefix operator is always active.

?

The same example as before can be written:

%START AA BB CC%%^a {ECHO; BEGIN AA;}^b {ECHO; BEGIN BB;}^c {ECHO; BEGIN CC;}\n {ECHO; BEGIN 0;}<AA>magic printf("first");<BB>magic printf("second");<CC>magic printf("third");

where the logic is exactly the same as in the previous method of handling the problem, but Lex does the work rather than the user's code.

?

11. Character Set.

The programs generated by Lex handle character I/O only through the routines input, output, and unput. Thus the character representation provided in these routines is accepted by Lex and employed to return values in yytext. For internal use a character is represented as a small integer which, if the standard library is used, has a value equal to the integer value of the bit pattern representing the character on the host computer. Normally, the letter a is represented as the same form as the character constant 'a'. If this interpretation is changed, by providing I/O routines which translate the characters, Lex must be told about it, by giving a translation table. This table must be in the definitions section, and must be bracketed by lines containing only ``%T''. The table contains lines of the form

{integer} {character string}

?

which indicate the value associated with each character. Thus the next example

%T1 Aa2 Bb...26 Zz27 \n28 +29 -30 031 1...39 9%TSample character table.

maps the lower and upper case letters together into the integers 1 through 26, newline into 27, + and - into 28 and 29, and the digits into 30 through 39. Note the escape for newline. If a table is supplied, every character that is to appear either in the rules or in any valid input must be included in the table. No character may be assigned the number 0, and no character may be assigned a bigger number than the size of the hardware character set.

?

12. Summary of Source Format.

?

The general form of a Lex source file is:

{definitions}%%{rules}%%{user subroutines}

The definitions section contains a combination of

1) Definitions, in the form ``name space translation''.

2) Included code, in the form ``space code''.

3) Included code, in the form

%{code%}

4) Start conditions, given in the form

%S name1 name2 ...

5) Character set tables, in the form

%Tnumber space character-string...%T

6) Changes to internal array sizes, in the form

%x nnn

?

where nnn is a decimal integer representing an array size and x selects the parameter as follows:

Letter Parameterp positionsn statese tree nodesa transitionsk packed character classeso output array size

?

Lines in the rules section have the form ``expression action'' where the action may be continued on succeeding lines by using braces to delimit it.

?

Regular expressions in Lex use the following operators:

x the character "x""x" an "x", even if x is an operator.\x an "x", even if x is an operator.[xy] the character x or y.[x-z] the characters x, y or z.[^x] any character but x.. any character but newline.^x an x at the beginning of a line.<y>x an x when Lex is in start condition y.x$ an x at the end of a line.x? an optional x.x* 0,1,2, ... instances of x.x+ 1,2,3, ... instances of x.x|y an x or a y.(x) an x.x/y an x but only if followed by y.{xx} the translation of xx from thedefinitions section.x{m,n} m through n occurrences of x

13. Caveats and Bugs.

There are pathological expressions which produce exponential growth of the tables when converted to deterministic machines; fortunately, they are rare.

?

REJECT does not rescan the input; instead it remembers the results of the previous scan. This means that if a rule with trailing context is found, and REJECT executed, the user must not have used unput to change the characters forthcoming from the input stream. This is the only restriction on the user's ability to manipulate the not-yet-processed input.

?

14. Acknowledgments.

As should be obvious from the above, the outside of Lex is patterned on Yacc and the inside on Aho's string matching routines. Therefore, both S. C. Johnson and A. V. Aho are really originators of much of Lex, as well as debuggers of it. Many thanks are due to both.

?

The code of the current version of Lex was designed, written, and debugged by Eric Schmidt.

?

15. References.

1. B. W. Kernighan and D. M. Ritchie,

The C Programming Language

Prentice-Hall, N. J. (1978).

2. B. W. Kernighan, Ratfor: A Preprocessor for a Rational Fortran, Software Practice and Experience, 5, pp. 395-496 (1975).

3. S. C. Johnson, Yacc: Yet Another Compiler Compiler, Computing Science Technical Report No. 32, 1975, Bell Laboratories, Murray Hill, NJ 07974.

4. A. V. Aho and M. J. Corasick,

Efficient String Matching: An Aid to Bibliographic Search

Comm. ACM 18, 333-340 (1975).

5. B. W. Kernighan, D. M. Ritchie and K. L. Thompson

QED Text Editor, Computing Science Technical Report No. 5, 1972

Bell Laboratories, Murray Hill, NJ 07974.

6. D. M. Ritchie, private communication. See also M. E. Lesk,

The Portable C Library

Computing Science Technical Report No. 31, Bell Laboratories, Murray Hill, NJ 07974.

轉載于:https://www.cnblogs.com/parsifal/archive/2012/05/08/2490203.html

總結

以上是生活随笔為你收集整理的语法分析生成器 - LEX的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久久久国产精华液 | 国产盗摄精品一区二区 | 91国内产香蕉| 97国产一区二区 | 亚洲.www | av中文字幕在线观看网站 | 免费av在线网站 | 久久婷婷精品视频 | 91爱爱电影 | 天堂av网在线 | 波多野结衣视频一区二区三区 | 九九热免费视频在线观看 | 91在线精品播放 | 中文字幕一区二区三区四区在线视频 | 久久久久久免费视频 | 在线成人高清电影 | www天天操 | 国内精品久久久久影院日本资源 | 成人久久久久久久久 | 一区二区三区在线播放 | 欧美精品v国产精品v日韩精品 | 久久中文欧美 | 狠狠狠狠狠狠狠干 | 高清av在线免费观看 | 国产精品6999成人免费视频 | 久久久久国产精品一区 | 91麻豆高清视频 | 国产精品久久久久久久久久免费看 | 亚洲国产偷 | 成年人电影免费看 | 99视频在线精品国自产拍免费观看 | 久久久久亚洲精品 | 国产精品片 | 一区二区三区免费在线观看视频 | 中文资源在线官网 | 国产精品久久久久久久久久久久 | 五月婷在线播放 | 久久久久女教师免费一区 | 国产探花视频在线播放 | 欧美一级日韩三级 | 国产精品久久久久影院 | 日韩精品中文字幕av | 精品久久久久国产免费第一页 | 国产99精品| 最新av在线播放 | 亚洲影视资源 | 免费日韩一区二区三区 | 久久精品电影院 | 天天爱天天操 | 四虎在线观看视频 | 中文字幕久久网 | 久久久久亚洲国产 | 在线国产91 | 日韩在线免费播放 | 亚洲影院天堂 | 91热视频| 黄色app网站在线观看 | 99资源网| 最近2019中文免费高清视频观看www99 | 久草在线观看视频免费 | 一区二区三区中文字幕在线观看 | 精品亚洲va在线va天堂资源站 | 999日韩 | 色婷婷激情电影 | 超碰97网站| 国产中文字幕免费 | 波多野结衣视频一区 | 狠狠操操| 182午夜在线观看 | 黄色一二级片 | a视频免费在线观看 | 国产亚洲字幕 | 四虎影视av | 亚洲伦理电影在线 | 一级片免费观看视频 | 日韩av不卡在线观看 | 婷婷六月综合网 | 日韩三级不卡 | 蜜臀久久99精品久久久无需会员 | 三级动图| 国产 视频 高清 免费 | 激情综合五月天 | 日本深夜福利视频 | 一级国产视频 | 久草在线观看 | 欧美日韩国产在线精品 | 91成人看片 | 麻豆首页| 免费99精品国产自在在线 | 狠狠干天天色 | 99在线精品视频在线观看 | 久草在线视频国产 | 久久新| 国产在线欧美日韩 | 国产亚洲精品久久久久久网站 | 亚洲自拍自偷 | 久久国内精品视频 | 二区三区av | 探花视频在线观看免费版 | 久久久国产精品网站 | 99久高清在线观看视频99精品热在线观看视频 | 99中文视频在线 | 亚洲黄色在线 | 免费国产亚洲视频 | 免费网站在线观看人 | 成人黄色片在线播放 | 在线观看国产成人av片 | 在线国产视频观看 | 射久久| 日韩二区精品 | 日日夜夜狠狠操 | 精品国产一区二区三区久久久蜜月 | 久草免费资源 | 久久精品国产精品亚洲 | 日韩在线观看你懂得 | 黄色片网站 | 美女久久| 天天色天天操天天爽 | 国产午夜不卡 | 激情五月色播五月 | 国产激情小视频在线观看 | 三级av小说| 亚洲国产人午在线一二区 | 青春草视频在线播放 | 日韩电影在线观看中文字幕 | 亚州精品一二三区 | 福利一区二区 | 久久久国产精品人人片99精片欧美一 | 欧美视屏一区二区 | 久草剧场 | 五月婷在线| 日韩高清一区二区 | 日韩免费播放 | 在线观看国产成人av片 | 久久区二区 | 国产一区二区在线免费 | 美女免费视频一区二区 | 久久艹艹 | 天天添夜夜操 | 成人午夜片av在线看 | 青青河边草免费直播 | 国产精品手机看片 | 美女黄色网在线播放 | 国产精品原创视频 | 天天做天天干 | 综合久久影院 | 999成人| 韩国在线一区二区 | 免费看短| 久久字幕精品一区 | 在线播放第一页 | 97人人模人人爽人人喊中文字 | 美女网站色 | 97超碰中文字幕 | 综合久久2023 | 欧美aa级 | 精品久久一区二区 | 免费av一级电影 | 97超碰人人网 | 久久精品国产精品亚洲 | 五月开心六月婷婷 | 国产v亚洲v | 亚洲精品午夜久久久 | 国产99久久 | 九九激情视频 | 91黄在线看 | 日韩亚洲在线视频 | 激情综合五月天 | 国产精品女视频 | 黄色三级免费片 | 911亚洲精品第一 | 欧美片网站yy | 97超在线 | 亚洲欧洲精品一区二区精品久久久 | 最近日本中文字幕 | 亚洲欧美成人在线 | 国产成人av一区二区三区在线观看 | 深夜福利视频一区二区 | 日韩美在线观看 | 国产一区二区午夜 | 婷婷五月在线视频 | 91精品视频免费在线观看 | 一区二区不卡高清 | 欧美另类人妖 | 久久五月天婷婷 | 国产精品亚州 | 国产小视频免费在线网址 | 成人av动漫在线观看 | 国产成人一区二区三区免费看 | 奇米四色影狠狠爱7777 | 欧美一区二区在线 | 中文字幕网站视频在线 | 欧美成天堂网地址 | 日韩簧片在线观看 | 国产精品3| 日本黄色大片免费看 | 麻豆91网站| 超碰97成人| 亚洲年轻女教师毛茸茸 | 91在线中字 | 热久久免费国产视频 | 天天干天天摸天天操 | 久久久精品二区 | 久草免费新视频 | 国产精品久久久久久久久婷婷 | www.亚洲精品 | 激情久久伊人 | 一区二区不卡视频在线观看 | 国产精品亚 | 久久免费视频99 | 精品国产91亚洲一区二区三区www | 日韩一区二区三区不卡 | 97成人精品视频在线播放 | 91完整版在线观看 | 四虎4hu永久免费 | 激情欧美xxxx | 成人久久精品视频 | 亚洲爽爽网 | 亚洲精品欧美成人 | 日本黄色免费在线观看 | 视频一区二区在线观看 | 特黄特黄的视频 | 香蕉91视频 | 久久大香线蕉app | 久久久高清一区二区三区 | 亚洲春色综合另类校园电影 | 91自拍视频在线 | 婷婷色亚洲 | 色吧久久 | 一区二区三区av在线 | 婷婷香蕉 | 国产69精品久久99不卡的观看体验 | 国产精品久久久久久久久久 | 香蕉97视频观看在线观看 | 久久在草 | 在线婷婷| 色噜噜狠狠狠狠色综合 | 国产热re99久久6国产精品 | 亚洲精品国产欧美在线观看 | 青草草在线视频 | 欧美三级高清 | 成人黄色在线电影 | 看av免费网站 | 国产色a在线观看 | jizz999| 黄色国产在线观看 | 香蕉网在线播放 | 超级碰碰碰碰 | 成人免费视频网站在线观看 | 国产精品av一区二区 | 亚洲精品www久久久 www国产精品com | 黄色午夜网站 | 国产精品一区二区三区观看 | 欧美日韩二区在线 | 91丨九色丨蝌蚪丨对白 | 国产麻豆精品传媒av国产下载 | 成人毛片在线观看 | 99久久精品视频免费 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 久久成人免费 | 精品在线亚洲视频 | 精品国产乱码久久久久久1区二区 | 中文字幕色婷婷在线视频 | 日批在线看 | 国产在线更新 | 男女激情片在线观看 | wwwwww色| 欧美天天综合 | 综合色婷婷 | 久久99久久99免费视频 | 亚洲毛片久久 | 天堂在线免费视频 | 中文字幕区 | 国产成人精品一区二区三区福利 | 中国精品一区二区 | 成人97视频一区二区 | 亚洲第五色综合网 | 国产精品自产拍在线观看桃花 | 一区二区三区四区五区在线 | 在线a人v观看视频 | 国产精品一区欧美 | 日韩欧美在线第一页 | 国产综合91 | 国产一区二区三区午夜 | 久久久久看片 | 91网页版免费观看 | 中文字幕日本电影 | 91丝袜美腿 | 热久久99这里有精品 | 精品在线观看一区二区 | 精品国产乱码久久久久久久 | 日日天天av | 天堂av网在线| 色窝资源 | 成人免费在线播放 | 久久99热精品 | 久久久精品99 | 中文字幕亚洲欧美日韩2019 | 国产精品手机视频 | 国产专区视频在线观看 | 日韩高清在线观看 | 国产精品乱看 | 美女av电影 | 黄色av影视 | 国际精品久久 | 国产精品美女在线 | 中文字幕婷婷 | 国产资源网 | 久久五月婷婷丁香社区 | 五月婷婷六月综合 | 麻豆视频在线免费看 | 黄色午夜网站 | 精品亚洲欧美无人区乱码 | 欧美在线视频一区二区 | 色综合久久网 | 亚洲人成精品久久久久 | 免费黄色在线网址 | 中文字幕在线看 | 91人人爽久久涩噜噜噜 | 久久久亚洲麻豆日韩精品一区三区 | 黄色软件视频网站 | 国产在线 一区二区三区 | 在线观看免费高清视频大全追剧 | 蜜桃传媒一区二区 | 97综合网| 操操日日| 亚洲aⅴ乱码精品成人区 | 免费成人黄色片 | 超碰在线97观看 | 国产午夜精品一区 | 手机在线中文字幕 | 视频一区二区在线 | www看片网站 | 狠狠狠色丁香婷婷综合久久88 | 在线观看不卡视频 | 亚洲精品久久久久中文字幕二区 | 欧美一级视频免费看 | 2023天天干| 成人在线视频网 | 天天爱天天操天天干 | 国产视频不卡一区 | 国产精品女同一区二区三区久久夜 | 久久夜夜夜| 色婷婷国产精品一区在线观看 | 91精品国产99久久久久 | 日韩系列在线 | 亚洲一区精品二人人爽久久 | 久久成人精品视频 | 精品视频免费久久久看 | 日韩影视在线观看 | 久久免费影院 | 国产精品少妇 | 欧美日在线 | 91久久爱热色涩涩 | 中文日韩在线 | 婷婷在线视频观看 | 欧美日韩二区在线 | 欧美国产精品一区二区 | 天天干人人干 | 色开心| 91成人亚洲 | 五月天中文在线 | 国产中文字幕网 | 免费三及片| 91精品国产综合久久福利 | 免费麻豆视频 | 亚洲三级黄色 | 高清av网| 蜜臀精品久久久久久蜜臀 | 成人免费网站视频 | av在线播放快速免费阴 | 亚洲精品视频网址 | 久久美女免费视频 | 8x成人在线 | 99视频精品免费观看, | 伊人www22综合色 | 久久久电影网站 | 开心丁香婷婷深爱五月 | 免费成人黄色av | 成人毛片在线视频 | 国产专区视频在线 | 久久国产精品久久久久 | 亚洲伊人网在线观看 | 亚洲黄色在线观看 | 九九欧美视频 | 国产在线国偷精品产拍免费yy | 国产+日韩欧美 | 国产日韩欧美精品在线观看 | www天天干 | 欧美日韩性视频 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 国产成人精品久久久久 | 国产99一区视频免费 | 亚洲精品国产精品国自产 | 亚洲涩涩网| 91综合视频在线观看 | 免费看片网址 | 成人午夜av电影 | 亚洲在线免费视频 | 91中文字幕一区 | 好看av在线| 婷色在线 | 精品国产伦一区二区三区观看说明 | 在线观看视频福利 | 久久免费在线观看视频 | 久久成人国产精品一区二区 | 91大神精品视频在线观看 | 特级西西444www高清大视频 | 九色精品免费永久在线 | 伊人婷婷 | 成av人电影 | 久久精品欧美一区二区三区麻豆 | 日韩精品中文字幕在线不卡尤物 | 韩国av免费| 亚洲欧洲xxxx| 制服丝袜天堂 | 国产精品theporn | 精品美女在线观看 | 在线视频观看亚洲 | 天天干天天操av | 欧美视频xxx| 国产日韩精品一区二区三区 | 国产精品久久久久久久久久久久午 | 在线亚洲高清视频 | www.亚洲激情.com | 免费看av在线 | 欧美精品三级在线观看 | 精品欧美小视频在线观看 | 国产在线观看a | 国产在线国偷精品产拍免费yy | 91成人在线免费观看 | 免费视频成人 | 欧美一级黄大片 | 米奇狠狠狠888 | 日韩精品久久久 | 99久久99久久精品国产片果冰 | 中文字幕 国产 一区 | 天天爱天天操天天干 | 人人澡人人干 | 亚洲三级视频 | 在线国产视频 | 九九久久精品 | 国产精品日韩欧美一区二区 | 天天草夜夜 | 97超碰在线资源 | 国产精品久久久久久久电影 | 欧美 日韩精品 | 最近在线中文字幕 | 高潮毛片无遮挡高清免费 | 国产精品都在这里 | 亚洲国产精久久久久久久 | 91人人人 | 在线观看视频免费播放 | 亚洲精品久久久久久国 | 亚洲国产中文字幕在线视频综合 | 国产精品久久久久永久免费 | 久久精品亚洲精品国产欧美 | 色91av| 国产精品一区二区白浆 | 免费91在线 | 麻豆视频国产 | 91精品国产网站 | 丁香综合av | 91麻豆免费版| 中文字幕视频在线播放 | 婷婷色吧 | 欧美日韩精品二区第二页 | 日韩精品欧美一区 | av天天在线观看 | 一二区av| 欧美日韩视频免费 | 国产精品一区二区62 | 女人高潮特级毛片 | 九九热re| 成年人在线看片 | 天天综合天天综合 | 欧美精品二 | 一区二区三区免费 | 国产一级电影网 | 免费亚洲电影 | 91精品一区在线观看 | 超碰在线中文字幕 | 色一级片 | 国产福利91精品一区 | 久久久久国产精品厨房 | 高清中文字幕 | 久久久久久综合 | 国产精品永久免费在线 | a黄色大片 | 超碰伊人网 | 美女网站视频免费都是黄 | 久久亚洲精品国产亚洲老地址 | 欧美在线观看禁18 | av免费观看高清 | 天天射天天操天天 | 日韩免费成人av | 嫩模bbw搡bbbb搡bbbb | 少妇高潮冒白浆 | 日本巨乳在线 | 免费看成人 | 成人免费视频网站在线观看 | 97色婷婷人人爽人人 | 久久亚洲欧美 | av成人免费 | 成人a视频在线观看 | 中文字幕文字幕一区二区 | 免费毛片一区二区三区久久久 | 一区二区欧美日韩 | 成人午夜av电影 | 91视频久久久久 | 在线观看日本高清mv视频 | av免费看看 | 日韩av播放在线 | 激情欧美xxxx | 午夜久久福利 | av电影免费在线 | 热久久最新地址 | 91最新国产 | 深爱激情av | 狠狠综合网 | 亚洲高清久久久 | 国产精品理论片在线观看 | 成人av高清在线 | 在线观看亚洲 | 在线观看电影av | 一级免费片 | 91亚洲国产成人久久精品网站 | 97视频在线观看视频免费视频 | 97在线视频免费 | 亚洲精品1区2区3区 超碰成人网 | 免费在线观看av的网站 | 91成人午夜| 免费在线观看中文字幕 | 国产精品电影一区二区 | 精品久久久久久久久久 | 亚洲 综合 精品 | 免费网站观看www在线观看 | 欧美日韩精品免费观看视频 | 亚洲精品国精品久久99热一 | 国产剧情一区在线 | 午夜免费福利视频 | 麻豆久久久 | 久艹视频在线观看 | av成人在线播放 | 九九色在线观看 | 在线观看免费色 | 激情图片qvod | 国产精品毛片一区视频播不卡 | 免费a v在线| 日韩免费大片 | 一区二区三区四区不卡 | 热久久最新地址 | 狠狠色噜噜狠狠狠狠 | 国产成人精品av在线 | 亚洲特级片 | avsex| 精品主播网红福利资源观看 | 国内精品久久久久久久影视简单 | 国产成人精品aaa | 色丁香综合 | 国产精品久久久久久一区二区 | 免费一级黄色 | 99久国产| 国产亚洲精品久久久久久网站 | 国产黄免费 | 福利av影院 | 亚洲h在线播放在线观看h | 国产精品久久久久久久久久不蜜月 | 久久成人黄色 | 亚洲在线黄色 | 国产一级黄色片免费看 | 四季av综合网站 | 日韩精品观看 | 奇米7777狠狠狠琪琪视频 | 成人久久精品 | 99精品视频在线播放观看 | 在线中文字幕播放 | 99久久精品国产一区二区成人 | 91理论片午午伦夜理片久久 | 婷婷丁香花 | 九九九在线观看视频 | 国产麻豆精品传媒av国产下载 | 99热手机在线观看 | 黄色在线观看网站 | 色婷婷综合久久久久 | 久久视频在线看 | 成人91av | 国产在线视频不卡 | 美女网站免费福利视频 | 波多野结衣精品在线 | 欧美日韩免费看 | 综合久久五月天 | 精品亚洲免费 | 欧美伦理一区 | 久久久亚洲麻豆日韩精品一区三区 | 天天拍天天操 | 亚洲免费精品一区二区 | 欧美亚洲免费在线一区 | 免费看片网站91 | 日本精品视频一区 | 久久综合久久综合久久综合 | 波多野结衣在线视频一区 | 精品久久中文 | 精品夜夜嗨av一区二区三区 | 亚洲日本在线一区 | 日韩中文字幕在线 | 六月丁香综合 | 欧美最猛性xxx | 九九免费在线观看视频 | 国产亚洲小视频 | 久久av网址 | 美女视频黄频大全免费 | 亚洲天堂网在线观看视频 | 韩国av不卡| 久久精品免费看 | 日韩av成人在线 | 怡红院久久 | 天天干天天干天天干 | 2019天天干夜夜操 | 精品久久中文 | av天天在线观看 | 在线成人免费 | 国产精品久久久久婷婷二区次 | 日韩在线一二三区 | 亚洲午夜久久久综合37日本 | 日韩欧美一二三 | 欧美不卡在线 | 丝袜美腿亚洲 | 亚洲精品乱码久久久久久蜜桃不爽 | 青青草在久久免费久久免费 | 久久综合免费视频影院 | 美女激情影院 | 97视频在线观看播放 | 亚洲理论视频 | 日本一区二区免费在线观看 | 天天激情天天干 | 91精品日韩| 久久成人在线 | 成人在线免费小视频 | 久久久综合九色合综国产精品 | 日韩精品久久久免费观看夜色 | 欧美一级久久久久 | 日本中文乱码卡一卡二新区 | 国产三级精品三级在线观看 | 久99久中文字幕在线 | 99色在线视频 | 一区二区三区在线播放 | 午夜精品久久久 | 久久草视频 | 91成人在线视频 | 色91av | 久久综合干 | 欧美一区免费在线观看 | 欧美在线91| 久久久免费观看 | 成年人免费看的视频 | 黄色毛片视频免费观看中文 | 2021国产精品 | 成人av免费在线看 | 国产日韩欧美在线观看视频 | 日本成人中文字幕在线观看 | www亚洲精品 | 欧美日韩一区二区在线观看 | www.com在线观看| 久久国产日韩 | 中文有码在线 | 国产小视频在线免费观看 | 夜夜干夜夜 | www.久久精品视频 | 精品视频| 国产精品福利无圣光在线一区 | 五月婷婷操| 欧美综合国产 | 免费日韩 精品中文字幕视频在线 | 99精品视频免费在线观看 | 狠狠色丁香久久婷婷综合丁香 | 超碰人人草人人 | 亚洲日本va午夜在线电影 | 免费成人在线网站 | 久久你懂得 | 国产精品男女视频 | 最新av网站在线观看 | 深夜免费福利视频 | 国产高清在线不卡 | 手机av在线网站 | 国产成人精品一区二三区 | 免费看的视频 | 五月天久久综合 | 国产精品免费久久久久久 | 亚洲色图27p | 亚洲精品字幕在线 | 色中色综合 | 97超碰中文| 五月激情亚洲 | 九九热在线观看 | 免费观看丰满少妇做爰 | 美女精品国产 | 又黄又刺激又爽的视频 | 久久久久蜜桃 | 国产亚洲在线视频 | 国产成人资源 | 亚洲激情 | 午夜精品久久久久久久99水蜜桃 | 国产99区| 欧美一区二区精品在线 | 久久怡红院 | 亚洲色图美腿丝袜 | 日韩av电影免费观看 | 国产黄色片免费看 | 久亚洲| 91天堂在线观看 | 国产色在线,com | 奇米导航 | 国产99久久久国产精品成人免费 | 麻豆视频免费看 | 久久天堂精品视频 | 久久久天堂 | 欧美日韩国产精品一区二区亚洲 | 天天综合狠狠精品 | 波多野结衣在线视频一区 | 久久久黄色av | 国产成人av电影在线 | 97夜夜澡人人双人人人喊 | 日韩午夜av | 色婷婷狠 | 一区二区视频播放 | 青青草国产在线 | 丁香九月婷婷 | 久久综合色天天久久综合图片 | 日韩高清免费在线 | 日本精品在线看 | 免费观看国产视频 | 色欧美综合 | 99久久久久久 | 国产视频久久久久 | 丁香综合 | 日本中文字幕在线一区 | 992tv又爽又黄的免费视频 | 丁香花中文在线免费观看 | 午夜少妇一区二区三区 | 精品国产资源 | 日韩高清精品免费观看 | 丁香视频| 欧美巨乳网| 国内精品久久久久久 | 欧美日韩不卡一区二区三区 | 色婷婷综合久色 | 精品国产99| 欧美在线视频免费 | 成人久久免费 | 久久精品美女视频网站 | 中文字幕在线观看一区二区 | 91麻豆精品国产91 | 亚洲dvd| 欧美性受极品xxxx喷水 | 国产精品国内免费一区二区三区 | 午夜影视av| 不卡电影免费在线播放一区 | 97国产在线播放 | 六月色丁香 | 在线观看你懂的网站 | 午夜久久久久久久久 | 日韩av免费一区二区 | 2017狠狠干 | 亚洲自拍偷拍色图 | 一级免费观看 | 国产手机视频在线播放 | 亚洲日本精品视频 | 日日夜夜操操操操 | 日韩大片在线 | 麻豆视频国产精品 | 免费在线观看视频一区 | 成人国产精品久久久春色 | 日韩欧美精品一区 | 久久久久久毛片 | 久久人91精品久久久久久不卡 | 五月的婷婷 | av大片网站| 久久精品免费 | 香蕉视频久久久 | 亚洲九九影院 | 手机看国产毛片 | 五月的婷婷 | av成人黄色| 日本中文字幕免费观看 | 日日干狠狠操 | v片在线看 | 中文字幕一二 | bayu135国产精品视频 | 欧美a√在线 | 在线观av | 五月在线| 国产一区免费在线观看 | 91xav| 免费在线观看毛片网站 | 亚洲天堂网站 | www操操 | 成人一级视频在线观看 | 精品国产区 | 五月天欧美精品 | 六月天色婷婷 | 天天夜操| 九九久久免费视频 | 色av色av色av | 久久久久久免费视频 | 夜色资源网| 国产精品自产拍 | 国产精品久久久久久久久久久久冷 | 日韩午夜av | 91精品第一页 | 欧美国产精品久久久久久免费 | 中文字幕一区二区三区四区久久 | 午夜精品剧场 | 亚洲日韩中文字幕在线播放 | 久久精品久久精品久久39 | 免费在线中文字幕 | 国产成人精品一区一区一区 | 日韩av播放在线 | 久久免费视频国产 | 中文av在线播放 | 三级黄色网络 | 九九综合九九综合 | 久久久免费观看完整版 | 成人午夜网址 | 欧美久久久久久久久久久久久 | 美女免费网站 | 中文字幕在线视频网站 | 天天曰视频| 久久看片网 | 国产一区二区高清 | 五月婷婷色播 | 在线免费观看黄色大片 | h久久| 91av在线不卡 | 欧美成人黄 | 久久草av| 最新91在线视频 | 亚洲理论影院 | 2018好看的中文在线观看 | 又黄又爽又无遮挡的视频 | 干干夜夜| 亚洲国产精品成人精品 | 成人三级黄色 | 久草免费新视频 | 欧美日韩一区三区 | 亚洲午夜精品一区二区三区电影院 | 日韩不卡高清 | 黄色一级大片免费看 | 久久精品亚洲精品国产欧美 | 国产精品久久久久av福利动漫 | 97在线视频免费看 | 美女国产 | 五月开心婷婷 | 国产xxxx性hd极品 | 国产最新91 | 成人夜晚看av | 草久久精品| 天天干,天天射,天天操,天天摸 | 国产亚洲日 | 天天干天天射天天爽 | 国产一二三精品 | 欧美日韩成人一区 | 久久久免费视频播放 | 国产黄色电影 | 久久久www成人免费精品 | 在线免费观看的av | 亚洲激情在线 | 91伊人久久大香线蕉蜜芽人口 | 久久综合视频网 | 欧美精品久久人人躁人人爽 | 亚洲作爱视频 | 丁香婷婷色 | 欧美亚洲一区二区在线 | 97在线精品| 在线亚洲人成电影网站色www | 国产 日韩 欧美 中文 在线播放 | 91大神精品视频在线观看 | 99国产精品视频免费观看一公开 | 友田真希x88av | 黄色资源在线观看 | 亚洲精品看片 | 超碰97国产精品人人cao | 国产成人精品久久二区二区 | 色婷婷av国产精品 | 一区免费在线 | 久久免费精彩视频 | 五月天激情综合 | 91网站在线视频 | 国产精品普通话 | 91av在线视频免费观看 | 精品国产一区二区三区日日嗨 | 精品一区二区亚洲 | 精品久久久久久电影 | 国产精品久久久一区二区 | 日韩性网站 | 久久久久成人免费 | 国产理伦在线 | 国产精品午夜在线 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 欧美日韩精品影院 | 精品在线二区 | 在线视频区| 亚洲综合网站在线观看 | 欧美日韩亚洲在线观看 | 五月婷婷中文字幕 | 国产 欧美 日产久久 | 91人人视频在线观看 | 精品亚洲在线 | av看片网址 | 国产区精品视频 | av色图天堂网 | 天天操狠狠操网站 | 9在线观看免费高清完整版在线观看明 | 人人澡人人澡人人 | 日韩免费看 | 亚洲精品777 | 超碰在线观看99 | 亚洲a网| 黄色三级免费观看 | 在线视频一区观看 | 色婷婷综合久久久中文字幕 | 1024久久 | 国产精品露脸在线 | 国产精品1000| 久久久久久久久影院 | 免费三级黄 | 亚洲一二三久久 | 久久精品一区二区三区四区 | 最新午夜电影 | 久久女同性恋中文字幕 | 天天操天天色天天射 | 深爱激情五月婷婷 | 日韩视频在线一区 | 天天操天天干天天爱 | 国产高清第一页 | 欧日韩在线视频 | 青青草在久久免费久久免费 | 色婷婷精品大在线视频 | 可以免费观看的av片 | 日韩网站中文字幕 | 丁香六月婷婷激情 | 在线 你懂 | 激情久久婷婷 | 美女视频黄网站 | 在线观看av免费观看 | 成年人在线观看免费视频 | 日韩特级片 | 波多野结衣在线观看一区二区三区 | 国产最新在线观看 | 97电影网手机版 | 国产精彩视频一区二区 | 天天操天天干天天干 | 亚洲日本在线一区 | 国产日产av | 精品久久久一区二区 | 黄色大片av | 在线一区二区三区 | 成人h电影 | 欧美精品一区二区三区四区在线 | 国产裸体无遮挡 | 国产精品美女免费视频 | 96国产精品视频 | 黄污污网站 | 日本爱爱免费视频 | 在线观看成人国产 | 免费的国产精品 | 51久久成人国产精品麻豆 | 九九热精品在线 | 9色在线视频 | 色五丁香 | 在线小视频 | 黄网站a | 精品视频在线视频 | 欧美日韩精品综合 | 在线国产激情视频 | 欧美成人h版在线观看 | 成人h在线 | www.黄色| 国产久视频 | 成人中文字幕+乱码+中文字幕 | 成片免费观看视频大全 | 91高清完整版在线观看 | 亚洲理论在线观看电影 | 草在线视频 | 久久久激情网 | 91传媒视频在线观看 | 在线视频欧美亚洲 | 成年人在线观看网站 | 欧美日韩精品免费观看视频 | 91精品久久久久久久久 | 在线a人v观看视频 | 美女视频黄免费的久久 | 成年人免费在线 | 欧美一区二区三区不卡 | 午夜精品久久久久久久99热影院 | 嫩嫩影院理论片 | 久久人人爽人人爽人人片av免费 | 亚洲精品videossex少妇 |