An automaton with a store memory , in addition to the current state, has a stack where it can write characters. At each step, the machine reads the next input character, plus the top character from the stack. In accordance with the triple (the current state, the input character, a character from the stack), the automaton chooses which state to go to and what to write to the stack instead of the read character. Writing to the stack is optional: you can simply erase the read character from there; so the stack can grow and shrink during operation. state 1: consider {
stack symbol: {EOF (stack is empty)
input character:
{write down {{stay in 1 write down {, stay in 1
} do not write anything, go to line 2 does not fit (1)
EOF string does not fit (2) string matches (3)
state 2: believe}
stack symbol: {EOF (stack is empty)
input character:
{line does not fit (4) line does not fit (4)
} do not write anything, stay in line 2 does not fit (5)
EOF string does not fit (6) string matches (7)
Notes: VALID: '{' VALID '}';
VALID:;
On the left, before the colon - variable; on the right is a piece of text that can come out of it, and which can contain variables, including recursive references to the variable being defined. VALID: '{' VALID '}' | ;
EXPR: NUM | EXPR OP EXPR; NUM: DIGIT | NUM DIGIT; DIGIT: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ; OP: '+' | '-' | '*' | '/';
22+3*4-5 would be recognized like this: '2' '2' '+' '3' '*' '4' '-' '5'
DIGIT DIGIT OP DIGIT OP DIGIT OP DIGIT
NUM DIGIT OP NUM OP NUM OP NUM
NUM OP EXPR OP EXPR OP EXPR
EXPR OP EXPR OP EXPR
EXPR OP EXPR
EXPR
And maybe so: '2' '2' '+' '3' '*' '4' '-' '5'
DIGIT DIGIT OP DIGIT OP DIGIT OP DIGIT
NUM DIGIT OP NUM OP NUM OP NUM
NUM OP EXPR OP EXPR OP EXPR
EXPR OP EXPR OP EXPR
EXPR OP EXPR
EXPR
In the first case, the expression is recognized as the product of the sum on the left and the difference on the right; in the second - in accordance with the rules of arithmetic. There are other options, except for the two.EXPR: NUM | EXPR OP NUM ;
NUM: DIGIT | NUM DIGIT ;
DIGIT: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ;
OP: '+' | '-' | '*' | '/' ;
Now, in the EXPR definition, the second operand is always a bare number, and therefore the parsing can only be like this: '2' '2' '+' '3' '*' '4' '-' '5'
DIGIT DIGIT OP DIGIT OP DIGIT OP DIGIT
NUM DIGIT OP NUM OP NUM OP NUM
NUM OP NUM OP NUM OP NUM
EXPR OP NUM OP NUM OP NUM
EXPR OP NUM OP NUM
EXPR OP NUM
EXPR
EXPR: TERM | EXPR '+' TERM | EXPR '-' TERM ;
TERM: NUM | TERM '*' NUM | TERM '/' NUM ;
NUM: DIGIT | NUM DIGIT ;
DIGIT: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ;
'2' '2' '+' '3' '*' '4' '-' '5'
DIGIT DIGIT '+' DIGIT '*' DIGIT '-' DIGIT
NUM DIGIT '+' NUM '*' NUM '-' NUM
NUM '+' TERM '*' NUM '-' TERM
TERM '+' TERM '-' TERM
EXPR '+' TERM '-' TERM
EXPR '-' TERM
EXPR
if (1) if (2) foo(); else bar(); if (1) if (2) foo(); else bar(); - can be constructed either as if (1) { if (2) foo(); else bar(); } if (1) { if (2) foo(); else bar(); } if (1) { if (2) foo(); else bar(); } , or as if (1) { if (2) foo(); } else bar(); if (1) { if (2) foo(); } else bar(); , if the grammar maker does not take care to ban one of the interpretations. state 1:
number: shift, go to 2
state 2:
remove 1 character from stack, write DIGIT there
if the state on the stack is 1 or 7 or 10, go to 3
if the state on the stack is 4 or 9, go to 5
state 3:
remove 1 character from stack, write NUM there
if the state on the stack is 1 or 10, go to 4
if the state on the stack is 7, go to 9
state 4:
number: shift, go to 2
otherwise: remove 1 character from the stack, write TERM there
if the state on the stack is 1, go to 6
if the state on the stack is 10, go to 11
state 5:
remove 2 characters from stack, write NUM there
if the state on the stack is 1, go to 4
if the state on the stack is 7, go to 9
state 6:
'*', '/': shift, go to 7
otherwise: remove 1 character from the stack, write EXPR there
if the state on the stack is 1, go to 8
state 7:
number: shift, go to 2
state 8:
EOF: expression recognized successfully
'+', '-': shift, go to 10
state 9:
number: shift, go to 2
otherwise: remove 3 characters from the stack, write TERM there
if the state on the stack is 1, go to 6
if the state on the stack is 10, go to 11
state 10: EXPR shift: EXPR '+' TERM or shift EXPR: EXPR '+' TERM
number: shift, go to 2
state 11:
'*', '/': shift, go to 7
otherwise: remove 3 characters from the stack, write EXPR there
if the state on the stack is 1, go to 8
22+3*4-5 :state 1, input "22 + 3 * 4-5", the stack is empty * number: shift, go to 2 state 2, input "2 + 3 * 4-5", stack '2', (1) * remove 1 character from the stack, write DIGIT there, go to 3 state 3, input "2 + 3 * 4-5", stack DIGIT, (1) * remove 1 character from the stack, write NUM there, go to 4 state 4, input "2 + 3 * 4-5", stack NUM, (1) * number: shift, go to 2 state 2, input "+ 3 * 4-5", stack '2', (4), NUM, (1) * remove 1 character from the stack, write DIGIT there, go to 5 state 5, input "+ 3 * 4-5", stack DIGIT, (4), NUM, (1) * remove 2 characters from the stack, write NUM there, go to 4 state 4, input "+ 3 * 4-5", stack NUM, (1) * remove 1 character from the stack, write TERM there, go to 6 state 6, input "+ 3 * 4-5", stack TERM, (1) * remove 1 character from the stack, write EXPR there, go to 8 state 8, input "+ 3 * 4-5", EXPR stack, (1) * '+': shift, go to 10 state 10, input "3 * 4-5", stack '+', (8), EXPR, (1) * number: shift, go to 2 state 2, input "* 4-5", stack '3', (10), '+', (8), EXPR, (1) * remove 1 character from the stack, write DIGIT there, go to 3 state 3, input "* 4-5", stack DIGIT, (10), '+', (8), EXPR, (1) * remove 1 character from the stack, write NUM there, go to 4 state 4, input "* 4-5", stack NUM, (10), '+', (8), EXPR, (1) * remove 1 character from the stack, write TERM there, go to 11 state 11, input "* 4-5", stack TERM, (10), '+', (8), EXPR, (1) * '*': shift, go to 7 state 7, input 4-5, stack '*', (11), TERM, (10), '+', (8), EXPR, (1) * number: shift, go to 2 state 2, input "-5", stack '4', (7), '*', (11), TERM, (10), '+', (8), EXPR, (1) * remove 1 character from the stack, write DIGIT there, go to 3 state 3, input "-5", stack DIGIT, (7), '*', (11), TERM, (10), '+', (8), EXPR, (1) * remove 1 character from the stack, write NUM there, go to 9 state 9, input "-5", stack NUM, (7), '*', (11), TERM, (10), '+', (8), EXPR, (1) * remove 3 characters from the stack, write TERM there, go to 11 state 11, input "-5", stack TERM, (10), '+', (8), EXPR, (1) * remove 3 characters from the stack, write EXPR there, go to 8 state 8, input "-5", EXPR stack, (1) * '-': shift, go to 10 state 10, input "5", stack '-', (8), EXPR, (1) * number: shift, go to 2 state 2, input is empty, stack is '5', (10), '-', (8), EXPR, (1) * remove 1 character from the stack, write DIGIT there, go to 3 state 3, input is empty, stack DIGIT, (10), '-', (8), EXPR, (1) * remove 1 character from the stack, write NUM there, go to 4 state 4, input is empty, stack NUM, (10), '-', (8), EXPR, (1) * remove 1 character from the stack, write TERM there, go to 11 state 11, input is empty, stack TERM, (10), '-', (8), EXPR, (1) * remove 3 characters from the stack, write EXPR there, go to 8 state 8, input is empty, EXPR stack, (1) * EOF: expression recognized successfully
state 1, input "22 + 3 * 4-5", the stack is empty * number: shift, go to 2 state 2, input "2 + 3 * 4-5", stack '2', (1) * remove '2' from the stack, write DIGIT = 2 there, go to 3 state 3, input "2 + 3 * 4-5", stack DIGIT = 2, (1) * remove DIGIT = 2 from the stack, write NUM = 2 there, go to 4 state 4, input "2 + 3 * 4-5", stack NUM = 2, (1) * number: shift, go to 2 state 2, input "+ 3 * 4-5", stack '2', (4), NUM = 2, (1) * remove the '2' character from the stack, write DIGIT = 2 there, go to 5 state 5, input "+ 3 * 4-5", stack DIGIT = 2, (4), NUM = 2, (1) * remove DIGIT = 2, NUM = 2 from the stack, write NUM = 22 there, go to 4 state 4, input "+ 3 * 4-5", stack NUM = 22, (1) * remove NUM = 22 from the stack, write TERM = 22 there, go to 6 state 6, input "+ 3 * 4-5", stack TERM, (1) * remove TERM = 22 from the stack, write EXPR = 22 there, go to 8 state 8, input "+ 3 * 4-5", stack EXPR = 22, (1) * '+': shift, go to 10 state 10, input "3 * 4-5", stack '+', (8), EXPR = 22, (1) * number: shift, go to 2 state 2, input "* 4-5", stack '3', (10), '+', (8), EXPR = 22, (1) * remove '3' from the stack, write there DIGIT = 3, go to 3 state 3, input "* 4-5", stack DIGIT = 3, (10), '+', (8), EXPR = 22, (1) * remove DIGIT = 3 from the stack, write NUM = 3 there, go to 4 state 4, input "* 4-5", stack NUM = 3, (10), '+', (8), EXPR = 22, (1) * remove NUM = 3 character from the stack, write TERM = 3 there, go to 11 state 11, input "* 4-5", stack TERM = 3, (10), '+', (8), EXPR = 22, (1) * '*': shift, go to 7 state 7, input “4-5”, stack '*', (11), TERM = 3, (10), '+', (8), EXPR = 22, (1) * number: shift, go to 2 state 2, input "-5", stack '4', (7), '*', (11), TERM = 3, (10), '+', (8), EXPR = 22, (1) * remove '4' from the stack, write there DIGIT = 4, go to 3 state 3, input "-5", stack DIGIT = 4, (7), '*', (11), TERM = 3, (10), '+', (8), EXPR = 22, (1) * remove DIGIT = 4 character from the stack, write NUM = 4 there, go to 9 state 9, input "-5", stack NUM = 4, (7), '*', (11), TERM = 3, (10), '+', (8), EXPR = 22, (1) * remove NUM = 4, '*', TERM = 3 from the stack, write TERM = 12 there, go to 11 state 11, input "-5", stack TERM = 12, (10), '+', (8), EXPR = 22, (1) * remove TERM = 12, '+', EXPR = 22 from the stack, write EXPR = 34 there, go to 8 state 8, input "-5", stack EXPR = 34, (1) * '-': shift, go to 10 state 10, input "5", stack '-', (8), EXPR = 34, (1) * number: shift, go to 2 state 2, input is empty, stack is '5', (10), '-', (8), EXPR = 34, (1) * remove '5' from the stack, write DIGIT = 5 there, go to 3 state 3, input is empty, stack DIGIT = 5, (10), '-', (8), EXPR = 34, (1) * remove DIGIT = 5 from the stack, write NUM = 5 there, go to 4 state 4, input is empty, stack NUM = 5, (10), '-', (8), EXPR = 34, (1) * remove NUM = 5 from the stack, write TERM = 5 there, go to 11 state 11, input is empty, stack TERM = 5, (10), '-', (8), EXPR = 34, (1) * remove TERM = 5, '-', EXPR = 34 from the stack, write EXPR = 29 there, go to 8 state 8, input is empty, stack EXPR = 29, (1) * EOF: expression recognized successfully, value = 29
Source: https://habr.com/ru/post/99298/
All Articles