259 lines
4.0 KiB
Bash
259 lines
4.0 KiB
Bash
#!/bin/dash
|
|
|
|
# Syntax scheme:
|
|
#
|
|
# hemar
|
|
# elements
|
|
#
|
|
# elements
|
|
# element
|
|
# element ws elements
|
|
#
|
|
# element
|
|
# tag
|
|
# text
|
|
#
|
|
# text
|
|
# text-item
|
|
# text-item text
|
|
#
|
|
# text-item
|
|
# '0020' . '10FFFF' - '{'
|
|
# nopatern
|
|
#
|
|
# tag
|
|
# '{[' ws path ws ']}'
|
|
# '{[' ws loop-statement ws ']}'
|
|
# '{[' ws include-header ws ']}'
|
|
# '{[' ws "end" ws ']}'
|
|
# '{[' ws function ws ']}'
|
|
#
|
|
# # loop tag
|
|
# loop-statemant
|
|
# "for" string "in" path
|
|
#
|
|
# # include tag
|
|
# include-header
|
|
# "include" path
|
|
#
|
|
# # fucntion tag
|
|
# function
|
|
# "compute" language function-body
|
|
# "compute" - function-body
|
|
#
|
|
# language
|
|
# "dash"
|
|
# "plpgsql"
|
|
#
|
|
# function-body
|
|
# ""
|
|
# '0020' . '10FFFF', function-body
|
|
#
|
|
# function-character
|
|
# '0020' . '10FFFF' - ']'
|
|
# ncpatern
|
|
#
|
|
# # path
|
|
# path
|
|
# "."
|
|
# segmented-path
|
|
#
|
|
# segmented-path
|
|
# segment
|
|
# segment "." segmented-path
|
|
#
|
|
# segment
|
|
# string
|
|
# index
|
|
#
|
|
# index
|
|
# '\' digit
|
|
# '\' onenine digits
|
|
# '\' '-' digit
|
|
# '\' '-' onenine digits
|
|
#
|
|
# # types
|
|
# string
|
|
# character
|
|
# character string
|
|
#
|
|
# character
|
|
# '0020' . '10FFFF' - '"' - '\' - '.' - ']'
|
|
# '\' escape
|
|
# ncpatern
|
|
#
|
|
# escape
|
|
# '.'
|
|
# ']}'
|
|
# '"'
|
|
# '\'
|
|
# '/'
|
|
# 'b'
|
|
# 'f'
|
|
# 'n'
|
|
# 'r'
|
|
# 't'
|
|
# 'u' hex hex hex hex
|
|
#
|
|
# hex
|
|
# digit
|
|
# 'A' . 'F'
|
|
# 'a' . 'f'
|
|
#
|
|
# digits
|
|
# digit
|
|
# digit digits
|
|
#
|
|
# digit
|
|
# '0'
|
|
# onenine
|
|
#
|
|
# onenine
|
|
# '1' . '9'
|
|
#
|
|
# # paterns
|
|
# ws
|
|
# ""
|
|
# '0020' ws
|
|
# '000A' ws
|
|
# '000D' ws
|
|
# '0009' ws
|
|
#
|
|
# nopatern
|
|
# '{' '0020' . '10FFFF' - '['
|
|
#
|
|
# ncpatern
|
|
# ']' '0020' . '10FFFF' - '}'
|
|
|
|
|
|
# AST Plex:
|
|
#
|
|
# Type = 0..=5
|
|
#
|
|
# Text = string # just a text body
|
|
#
|
|
# Interpolation = string # path to variable
|
|
#
|
|
# Include = string # path to include data
|
|
#
|
|
# Section = {
|
|
# v = string # item variable name for loop
|
|
# p = string # path to array for iteration
|
|
# b = [Element] # section body
|
|
#
|
|
# }
|
|
#
|
|
# End = null
|
|
#
|
|
# Compute = {
|
|
# l = string # programing language
|
|
# b = string # function body
|
|
# }
|
|
#
|
|
# Element = {
|
|
# t = Type # element type
|
|
# b = Text # element body
|
|
# | Interpolation
|
|
# | Section
|
|
# | End
|
|
# | Include
|
|
# | Compute
|
|
# }
|
|
#
|
|
# AbstarctSyntaxTree (ATS) = {
|
|
# e = [Element] # elements array
|
|
#}
|
|
AST=''
|
|
|
|
# 0 - text
|
|
# 1 - deside tag type
|
|
# 2 - interpolation
|
|
# 3 - section
|
|
# 4 - include
|
|
# 5 - compute
|
|
STAGE=0
|
|
STAGE_BUFFER="$(mktemp)"
|
|
open_tag_flag=0
|
|
|
|
# finds close pattern and store the char to the STAGE_BUFFER
|
|
find_close_pattern() {
|
|
char="${1:?}"
|
|
if [ "${close_tag_flag:?}" -eq 0 ] && [ "$char" = ']' ]; then
|
|
close_tag_flag=1
|
|
elif [ "${close_tag_flag:?}" -eq 1 ] && [ "$char" = '}' ]; then
|
|
close_tag_flag=0
|
|
|
|
# removes first and last white spaces from the buffer
|
|
sed -i 's/[[:space:]]$//g' "$STAGE_BUFFER"
|
|
sed -i 's/^[[:space:]]//g' "$STAGE_BUFFER"
|
|
|
|
# removes last char from buffer (]) is part of close pattern
|
|
truncate -s -1 "$STAGE_BUFFER"
|
|
return 0
|
|
else
|
|
printf '%s' "$char" >> "$STAGE_BUFFER"
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# finds open pattern and stores the char to the STAGE_BUFFER
|
|
find_open_pattern() {
|
|
char="${1:?}"
|
|
if [ "${open_tag_flag:?}" -eq 0 ] && [ "$char" = '{' ]; then
|
|
open_tag_flag=1
|
|
elif [ "${open_tag_flag:?}" -eq 1 ] && [ "$char" = '[' ]; then
|
|
open_tag_flag=0
|
|
|
|
# removes last char from buffer ({) is part of open pattern
|
|
truncate -s -1 "$STAGE_BUFFER"
|
|
return 0
|
|
else
|
|
printf '%s' "$char" >> "$STAGE_BUFFER"
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
parse() {
|
|
char="$1"
|
|
|
|
case "$STAGE" in
|
|
0)
|
|
if find_open_pattern "$char"; then
|
|
plex_set "$data_pointer"''
|
|
STAGE=1
|
|
fi
|
|
;;
|
|
1)
|
|
if find_close_pattern "$char"; then
|
|
STAGE=0
|
|
fi
|
|
;;
|
|
2)
|
|
|
|
;;
|
|
3)
|
|
|
|
;;
|
|
4)
|
|
|
|
;;
|
|
*)
|
|
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Using dd to read one character at a time
|
|
input=$(cat)
|
|
i=1
|
|
while :; do
|
|
char=$(printf '%s' "$input" | dd bs=1 skip=$((i-1)) count=1 2>/dev/null)
|
|
[ -z "$char" ] && break
|
|
|
|
parse "$char"
|
|
|
|
i=$((i+1))
|
|
done
|