%{
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
%}
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
%{
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Lint is unable to properly handle formats with wide strings
* (e.g. %ws) and misdiagnoses them as being malformed.
* This macro is used to work around that, by substituting
* a pointer to a null string when compiled by lint. This
* trick works because lint is not able to evaluate the
* variable.
*
* When lint is able to handle %ws, it would be appropriate
* to come back through and remove the use of this macro.
*/
#if defined(__lint)
static const char *lint_ws_fmt = "";
#else
#endif
void yyerror(char *);
%}
/* parser.y */
/* XCU4: add XSCON: %x exclusive start token */
/* XCU4: add ARRAY: %a yytext is char array */
/* XCU4: add POINTER: %p yytext is a pointer to char */
%left '/'
/*
* XCU4: lower the precedence of $ and ^ to less than the or operator
* per Spec. 1170
*/
%left '$' '^'
%left '|'
%left '*' '+' '?'
%{
#include "ldefs.h"
union _yystype_
{
int i;
};
int peekon = 0; /* need this to check if "^" came in a definition section */
%}
%%
%{
int i;
int j,k;
int g;
CHR *p;
%}
={
# ifdef DEBUG
# endif
}
;
={
}
| error
={
# ifdef DEBUG
if(debug) {
sect1dump();
sect2dump();
}
# endif
fatal = 0;
n_error++;
error("Illegal definition");
fatal = 1;
}
;
error("Too many definitions");
error("Definitions too long");
}
|
;
={
# ifdef DEBUG
# endif
sect++;
}
;
}
| pr
={ $$.i = $1.i;}
;
={
}
={
# ifdef DEBUG
# endif
fatal = 0;
yyline--;
n_error++;
error("Illegal rule");
fatal = 1;
yyline++;
}
r: CHAR
={ $$.i = mn0($1.i); }
| STR
={
i = mn0((unsigned)(*p++));
while(*p)
$$.i = i;
}
| '.'
={
}
| CCL
| NCCL
| r '*'
| r '+'
| r '?'
| r '|' r
| r '/' r
={ if(!divflg){
}
else {
error("illegal extra slash");
}
}
={ if($2.i > $4.i){
i = $2.i;
$2.i = $4.i;
$4.i = i;
}
if($4.i <= 0)
error("iteration range must be positive");
else {
j = $1.i;
for(k = 2; k<=$2.i;k++)
for(i = $2.i+1; i<=$4.i; i++){
g = dupl($1.i);
for(k=2;k<=i;k++)
}
$$.i = j;
}
}
| r ITER '}'
={
else {
j = $1.i;
for(k=2;k<=$2.i;k++)
$$.i = j;
}
}
| r ITER ',' '}'
={
/* from n to infinity */
else { /* >= 2 iterations minimum */
j = $1.i;
for(k=2;k<$2.i;k++)
}
}
| SCON r
/* XCU4: add XSCON */
| XSCON r
| '^' r
| r '$'
={ i = mn0('\n');
if(!divflg){
}
}
| '(' r ')'
={ $$.i = $2.i; }
| NULLS
/* XCU4: add ARRAY and POINTER */
| ARRAY
={ isArray = 1; };
| POINTER
={ isArray = 0; };
;
%%
int
yylex(void)
{
CHR *p;
int i;
CHR *t, c;
int n, j = 0, k, x;
static int sectbegin;
static int iter;
int ccs; /* Current CodeSet. */
int exclusive_flag; /* XCU4: exclusive start flag */
# ifdef DEBUG
yylval.i = 0;
# endif
while(!eof) {
switch(*p){
case '%':
switch(c= *(p+1)){
case '%':
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
p++;
while(*(++p))
if(!space(*p)) {
warning("invalid string following %%%% be ignored");
break;
}
}
lgate();
c = (int)myalloc(i,1);
if(c == 0)
error("Too little core for parse tree");
p = (CHR *)c;
free(p);
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
error("Too little core for parse tree");
case 'p': case 'P':
/* %p or %pointer */
if ((*(p+2) == 'o') ||
(*(p+2) == 'O')) {
if(lgatflg)
error("Too late for %%pointer");
while(*p && !iswspace(*p))
p++;
isArray = 0;
continue;
}
/* has overridden number of positions */
p += 2;
# ifdef DEBUG
# endif
continue;
case 'n': case 'N': /* has overridden number of states */
p += 2;
# ifdef DEBUG
# endif
continue;
case 'e': case 'E': /* has overridden number of tree nodes */
p += 2;
# ifdef DEBUG
# endif
continue;
case 'o': case 'O':
p += 2;
continue;
case 'a': case 'A':
/* %a or %array */
if ((*(p+2) == 'r') ||
(*(p+2) == 'R')) {
if(lgatflg)
error("Too late for %%array");
while(*p && !iswspace(*p))
p++;
isArray = 1;
continue;
}
/* has overridden number of transitions */
p += 2;
# ifdef DEBUG
# endif
continue;
case 'k': case 'K': /* overriden packed char classes */
p += 2;
# ifdef DEBUG
# endif
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
continue;
case 't': case 'T': /* character set specifier */
if(handleeuc)
error("\
Character table (%t) is supported only in ASCII compatibility mode.\n");
for(i = 0; i<ZCH; i++)
ctable[i] = 0;
error("Character value %d out of range",n);
continue;
}
while(digit(*p)) p++;
while(iswspace(*p)) p++;
t = p;
while(*t){
c = ctrans(&t);
if(ctable[(unsigned)c]){
if (iswprint(c))
warning("Character '%wc' used twice",c);
else
error("Chararter %o used twice",c);
}
else ctable[(unsigned)c] = n;
t++;
}
p = buf;
}
{
for(i=0; i<ZCH; i++)
chused[i]=0;
for(i=0; i<NCH; i++)
if (ctable[i]==0)
{
kr++;
}
}
lgate();
continue;
case 'r': case 'R':
c = 'r';
/* FALLTHRU */
case 'c': case 'C':
if(lgatflg)
error("Too late for language specifier");
ratfor = (c == 'r');
continue;
case '{':
lgate();
if(p[0]=='/' && p[1]=='*')
cpycom(p);
else
if(p[0] == '%') continue;
if (*p) error("EOF before %%%%");
else error("EOF before %%}");
break;
case 'x': case 'X': /* XCU4: exclusive start conditions */
exclusive_flag = 1;
goto start;
case 's': case 'S': /* start conditions */
exclusive_flag = 0;
lgate();
n = TRUE;
while(n){
t = p;
if(!isascii(*p))
error("None-ASCII characters in start condition.");
p++;
}
if(!*p) n = FALSE;
*p++ = 0;
if (*t == 0) continue;
i = sptr*2;
/* XCU4: save exclusive flag with start name */
error("Too many start conditions");
error("Start conditions too long");
}
continue;
default:
error("Invalid request %s",p);
continue;
} /* end of switch after seeing '%' */
break;
case ' ': case '\t': /* must be code */
lgate();
continue;
case '/': /* look for comments */
lgate();
/* FALLTHRU */
default: /* definition */
while(*p && !iswspace(*p)) p++;
if(*p == 0)
continue;
prev = *p;
*p = 0;
bptr = p+1;
warning("Substitution strings may not begin with digits");
}
} else { /* still sect 1, but prev != '\n' */
p = bptr;
while(*p && iswspace(*p)) p++;
if(*p == 0)
warning("No translation given - null string assumed");
prev = '\n';
}
}
error("unexpected EOF before %%%%");
/* end of section one processing */
lgate();
while(!eof){
switch(c=gch()){
case '\0':
if(n_error)error_tail();
return(freturn(0));
case '\n':
if(prev == '\n') continue;
x = NEWE;
break;
case ' ':
case '\t':
(void)cpyact();
/*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
while((c=gch()) && c != '\n');
continue;
}
if(cpyact()){
}
/*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
while((c=gch()) && c != '\n') {
if (c=='/') {
if((c=gch())=='*') {
c=gch();
while(c !=EOF) {
while (c=='*')
c = gch();
}
error("EOF inside comment");
} else
warning("undefined string");
} else if (c=='}')
error("illegal extra \"}\"");
w_loop: ;
}
/* while ((c=gch())== ' ' || c == '\t') ; */
/* if (!space(c)) error("undefined action string"); */
fatal = 0;
n_error++;
error("executable statements should occur right after %%%%");
fatal = 1;
continue;
}
x = NEWE;
break;
case '%':
else
continue;
}
if(peek == '%'){
c = gch();
c = gch();
x = DELIM;
break;
}
goto character;
case '|':
continue;
}
x = '|';
break;
case '$':
x = c;
break;
}
goto character;
case '^':
x = c;
break;
}
/* valid only at line begin */
x = c;
break;
case '?':
case '+':
case '*':
if(prev == '\n' ) {
fatal = 0;
n_error++;
error("illegal operator -- %c",c);
fatal = 1;
}
/* FALLTHRU */
case '.':
case '(':
case ')':
case ',':
case '/':
x = c;
break;
case '}':
x = c;
break;
case '{': /* either iteration or definition */
i = 0;
while(digit(c)){
token[i++] = c;
c = gch();
}
token[i] = 0;
if(first_test) {
first_test = FALSE;
first_value = yylval.i;
} else
ch = c;
x = ITER;
break;
}
else { /* definition */
i = 0;
while(c && c!='}'){
token[i++] = c;
if(i >= TOKENSIZE)
error("definition too long");
c = gch();
}
token[i] = 0;
if(i < 0)
else
if (peek == '^')
peekon = 1;
continue;
}
case '<': /* start condition ? */
goto character;
t = slptr;
do {
i = 0;
error("Non-ASCII characters in start condition.");
while(c != ',' && c && c != '>'){
token[i++] = c;
if(i >= TOKENSIZE)
error("string name too long");
error("None-ASCII characters in start condition.");
}
token[i] = 0;
if(i == 0)
goto character;
if(i < 0) {
fatal = 0;
n_error++;
fatal = 1;
continue;
}
*slptr++ = i+1;
} while(c && c != '>');
*slptr++ = 0;
/* check if previous value re-usable */
{
break;
while (*xp++);
}
if (xp<t)
{
/* re-use previous pointer to string */
slptr=t;
t=xp;
}
error("Too many start conditions used");
/* XCU4: add XSCON */
x = XSCON;
else
x = SCON;
break;
case '"':
i = 0;
/*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
remch(c);
token[i++] = c;
if(i >= TOKENSIZE){
warning("String too long");
i = TOKENSIZE-1;
break;
}
}
if(c == '\n') {
yyline--;
warning("Non-terminated string");
yyline++;
}
token[i] = 0;
if(i == 0)x = NULLS;
else if(i == 1){
x = CHAR;
}
else {
x = STR;
}
break;
case '[':
x = CCL;
if((c = gch()) == '^'){
x = NCCL;
c = gch();
}
i = 0;
while(c != ']' && c){
symbol[(unsigned)c] = 1;
c = gch();
continue;
}
if(c == '\\') {
}
/* range specified */
if (light) {
c = gch();
if(c == '\\')
remch(c);
k = c;
error("\
Character range specified between different codesets.");
if((unsigned)j > (unsigned)k) {
n = j;
j = k;
k = n;
}
if(!handleeuc)
if(!(('A'<=j && k<='Z') ||
('a'<=j && k<='z') ||
('0'<=j && k<='9')))
warning("Non-portable Character Class");
token[i++] = j;
token[i++] = k;
} else {
error("unmatched hyphen");
else symbol[(unsigned)c] = 1;
}
} else {
j = c;
remch(c);
token[i++] = c; /* Remember whatever.*/
}
c = gch();
}
/* try to pack ccl's */
token[i] = 0;
} else { /* not in ccl, add it */
error("Too many large character classes");
}
break;
case '\\':
default:
if(iter){ /* second part of an iteration */
if('0' <= c && c <= '9')
goto ieval;
}
remch(c);
i = 0;
token[i++] = c;
if(i >= TOKENSIZE) {
warning("string too long");
i = TOKENSIZE - 1;
break;
}
}
token[i] = 0;
if(i == 1){
x = CHAR;
}
else x = STR;
}
else {
yylval.i = (unsigned)c;
x = CHAR;
}
}
peekon = 0;
return(freturn(x));
/* NOTREACHED */
}
}
/* section three */
lgate();
ptail();
# ifdef DEBUG
if(debug)
# endif
else
}
return(freturn(0));
}
/* end of yylex */
# ifdef DEBUG
freturn(i)
int i; {
if(yydebug) {
(void) printf("now return ");
else (void) printf("%d",i);
(void) printf(" yylval = ");
switch(i){
break;
case CHAR:
break;
default:
break;
}
(void) putchar('\n');
}
return(i);
}
# endif