Ну вот предлагается на "суд толпы..........."
Вариант заточен под операторы Cи в основном под то что встречается в заголовочных файлах.
Сделан из postfix.fts от
mOleg-а
Здесь лежит все что надо одним архивом
http://files.mail.ru/5MI0JU запускать в последней весии форка
mOlegфайл
hpostfix.ftsПонимаются знаки чисел или выражений в скобках, операторы могут быть любой длины, есть контроль ошибок,
разбираются выражения вида
a+b(c<<d) значение которые предполагается вычислить и положить результат на стек. Выражение с присвоением например
а=b+c вызовет ошибку.
А также ошибку вызовут некотрые другие операторы Cи.
Знак изменяется использованием слова NEGATE -так проще всего получилось.
Пример: A*-B преобразуется в A B NEGATE * ; A/-(B-C) преобразуется в A B C - NEGATE /
_________________Итак начинаем пинать

______________
Код:
\ 19.02.2009 ~mOleg
\ Сopyright [C] 2009 mOleg mininoleg@yahoo.com
\ преобразование префиксной записи в постфиксную
\ Переработано _Harry
\ <<<<<< _Harry - так в дальнешем обозначаться мои изменения в postfix.fts <<<<<<<
rel/ xxWord.fts \ Поиск лексем и многосимвольных разделителей
\ string/ xWord.fts
\ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
stack/ stack.fts
memory/ box.fts
memory/ buff.fts
VOCABULARY TRANSL
ALSO TRANSL DEFINITIONS
\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
VARIABLE ListOp \ Адрес списка операторов
ListOp \ Начнем добавлять в список операторы
\ Коментарии после AddNode/ только в новой строке
\ так как читается вся строка
AddNode/ ,
AddNode/ ?
AddNode/ ;
AddNode/ =
\ Предыдущие операторы вызовут ошибку поэтому их в самое начало
AddNode/ <
AddNode/ >
AddNode/ |
AddNode/ &
AddNode/ ~
AddNode/ %
AddNode/ (
AddNode/ )
AddNode/ /
AddNode/ *
AddNode/ -
AddNode/ +
\ Самые употребительные ближе к хвосту списка будет быстрее разбор строки
AddNode/ ==
AddNode/ >>
AddNode/ <<
AddNode/ <=
AddNode/ =>
\ Самые длинные операторы в хвост списка чтобы раньше нашлись
\ особенно если есть совпадающие по символам но более короткие
DROP \ Закончили
\ Убрать пробелы перед лексемой
: nospace> ( asc # -- asc # ) OVER + SWAP
BEGIN DDUP >
WHILE DUP C@
Bl_ =
WHILE 1 + REPEAT
THEN SWAP OVER - ;
\ Убрать пробелы после лексемы
: <nospace ( asc # -- asc # ) OVER +
BEGIN DDUP < WHILE
1 - DUP C@
Bl_ = WHILE REPEAT
1 +
THEN OVER - ;
\ Заменить все символы табуляции в строке на пробелы
: notab ( asc # -- asc # ) DDUP OVER + SWAP
BEGIN DDUP >
WHILE DUP C@
Tab_ = IF Bl_ OVER C! THEN
1 +
REPEAT DDROP ;
\ Убрать пробелы и знаки табуляции из строки операнда и проверить что операнд один
: operand ( asc # -- asc # ) notab
nospace> <nospace
s" " SEARCH ABORT" Много операндов!" ;
\ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.
0xF00 CONSTANT buff#
USER-VALUE OutBuff
\ копировать содержимое строки в выходной буфер
: s>out ( asc # --> )
OutBuff >Buffer
IFNOT ERROR" Слишком длинная выходная строка!" THEN ;
\ переместить символ в выходной буфер
: c>out ( char --> ) SP@ 1 s>out DROP ;
\ если строка имеет не нулевую длину добавить ее в выходной буфер
: ~oper ( asc # --> ) *IF s>out Bl_ c>out ;THEN DDROP ;
\ --------------------------------------------------------------------------
0 VALUE oplist \ список операторов
\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
VARIABLE _)_ \ TRUE если последний разобраный оператор закрывающая скобка
\ Работа с операторами найти по имени оператор и выполнить его
\ укоротить строку источник по границе за оператором
\ a# -длина операнда; asc_s # -строка источник asc_o # -строка оператор
: ?operator ( l: a# d: asc_s # asc_o # -- asc_s # )
DDUP
oplist SEARCH-WORDLIST IF EXECUTE
ELSE ERROR" Неверный оператор!"
THEN + \ Адрес с которого продолжим разбор
ROT OVER - ROT + \ Укоротили разбираемую строку
LDROP ;
\ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
\ --------------------------------------------------------------------------
USER-VALUE operators \ стек для хранения отложенных операторов
0x20 CONSTANT operators# \ количество ячеек в стеке операторов
\ втолкнуть оператор на стек операторов
: adjourn ( addr --> ) operators PushTo ;
\ вытолкнуть оператор из стека операторов
: stretch ( --> addr ) operators PopFrom ;
\ прочесть верхний оператор в стеке операторов
: topmost ( --> addr ) operators ReadTop ;
\
: any ( --> # ) operators StackDepth ;
\ --------------------------------------------------------------------------
\ вернуть приоритет операции
: priority ( 'op --> pri ) B@ ;
\ добавить имя операции в выходной буфер
: operator ( 'op --> ) *IF 1 + COUNT ~oper ;THEN DROP ;
\ двухместная операция, то есть когда есть операнд слева и справа от операции
: twoseater ( 'op --> )
>L BEGIN topmost WHILE
topmost priority L@ priority < WHILENOT
stretch operator
REPEAT
THEN
L> adjourn
\ <<<<<
_)_ OFF ; \ >>>>>>
\ открывающая скобка
: LeftBracket ( 'op --> )
0 adjourn
twoseater
\ <<<<<
_)_ OFF ; \ >>>>>>
: <= ( n --> flag ) > 0 = ;
\ закрывающая скобка
: RigthBracket ( 'op --> )
>L BEGIN topmost WHILE
topmost priority L@ priority <= WHILE
stretch operator
REPEAT
THEN stretch DROP \ удаление нуля
L> adjourn
\ <<<<<
_)_ ON ; \ >>>>>>
VOCABULARY OPERATORS \ словарь, в котором находится список операций
ALSO OPERATORS CONTEXT @ TO oplist
THIS \ отсюда перечисляется список поддерживаемых операций -----------------
\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\ s" " S: ; \ пробелы просто пропускаются
\ Нет пробелы не считаются операторами
: == BOX[ 2 B, s" =" S", ]BOX twoseater ; \ логическое равно соответствует = в форте
: >> BOX[ 4 B, s" RSHIFT" S", ]BOX twoseater ;
: << BOX[ 4 B, s" LSHIFT" S", ]BOX twoseater ;
: <= BOX[ 4 B, s" <=" S", ]BOX twoseater ;
: => BOX[ 4 B, s" =>" S", ]BOX twoseater ;
: + L@ 0 XOR _)_ @ OR IFNOT ;THEN \ выход если установили что это знак а не оператор
BOX[ 3 B, s" +" S", ]BOX twoseater ;
: - L@ 0 XOR _)_ @ OR
IFNOT BOX[ 6 B, s" NEGATE" S", ]BOX \ если установили что это знак а не оператор
ELSE BOX[ 3 B, s" -" S", ]BOX
THEN twoseater ;
\ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
: * BOX[ 4 B, s" *" S", ]BOX twoseater ;
: / BOX[ 4 B, s" /" S", ]BOX twoseater ;
: % BOX[ 4 B, s" MOD" S", ]BOX twoseater ;
: & BOX[ 5 B, s" AND" S", ]BOX twoseater ; \ AND
: | BOX[ 5 B, s" OR" S", ]BOX twoseater ; \ OR
: ~ BOX[ 5 B, s" XOR" S", ]BOX twoseater ; \ XOR
: > BOX[ 2 B, s" >" S", ]BOX twoseater ; \ XOR
: < BOX[ 2 B, s" <" S", ]BOX twoseater ; \ XOR
: ( BOX[ 7 B, s" " S", ]BOX LeftBracket ; \ открывающая ( скобка
: ) BOX[ 7 B, s" " S", ]BOX RigthBracket ; \ закрывающая ) скобка
\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
: , ERROR" Макросы не поддерживаются!" ;
: ? ERROR" Условный оператор пока не сделан :( !" ;
: = ERROR" Приравнивание не поддерживается!" ;
: ; ERROR" Разделители недопустимы!" ;
\ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DEFINITIONS \ --------------------------------------------------------------
\ инициализировать стеки, необходимые переменные
: init ( --> )
operators IFNOT operators# NewStack TO operators THEN
operators ClearStack 0 adjourn
OutBuff *IF Clean ELSE DROP buff# Buffer TO OutBuff THEN
_)_ OFF ;
\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\ разбор выражения до конца строки
: expression ( asc # --> asc # )
init
S>HEAP DUP COUNT
BEGIN *WHILE
DDUP ListOp SearchOp
operand DUP >L ~oper
*IF ?operator
ELSE LDROP -ROT DDROP \ нет операторов - вся строка уже обработанна
THEN
REPEAT DDROP
BEGIN any WHILE stretch operator REPEAT
FREE THROW
OutBuff Buffer> ;
\ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RECENT ALSO TRANSL
\ взять выражение до конца строки, преобразовать его в постфикс, отобразить
: expr ( / expression --> )
Cr_ PARSE
DDUP TYPE ." == "
expression TYPE ;
\ преобразовать префиксную запись в постфиксную
: >postfix ( asc # --> asc # ) expression ;
PREVIOUS
\ EOF примеры использования ------------------------------------------------
CR expr a+b+c+d
CR expr a+ b+c+d
CR expr a +b+c+d
CR expr a + b+c+d
CR expr (a+b+c)+d
CR expr a+(b+c)+d
CR expr a==b+c*d&e
CR expr a&b*c+d==e
CR expr a+b*(a*(c+d))
CR expr ((a+b*a)+c)*d
.( \n\r\n\rнеплохо было бы скобки контролировать,\n\rа то вот чего >> )
expr ((((a+b)
.( \n\r\n\r-------числа со знаком-------\n\r)
CR expr -B
CR expr A*-B
CR expr A*(-B)
CR expr A*+B
CR expr (A <<- B) +C
CR expr A>>-B +( C*- D)
CR expr (A<<B)-V+( C*- D)
CR expr (a -+ b* - c)/d*-f<k